From e707212216c8586f2133b67dc8087e91ff3ca16c Mon Sep 17 00:00:00 2001 From: leoporoli Date: Mon, 5 Feb 2024 13:19:48 -0300 Subject: [PATCH] chore: debug APIC configuration and readme docs (#2112) ## Description: debug APIC configuration and readme docs ## Is this change user facing? NO ## References (if applicable): --------- Co-authored-by: Edgar Gomes Co-authored-by: Kevin Today Co-authored-by: mieubrisse --- .run/APIC-remote-debug.run.xml | 6 + README.md | 59 +- .../engine_service.pb.go | 562 +++++++++--------- .../lib/kurtosis_context/kurtosis_context.go | 102 +++- .../http_rest/api_types/api_types.gen.go | 18 +- .../engine_rest_api/engine_server.gen.go | 55 +- api/openapi/specs/kurtosis_api.yaml | 11 + api/protobuf/engine/engine_service.proto | 4 + api/rust/src/engine_api.rs | 4 + .../connect/engine_service_pb.d.ts | 8 + .../connect/engine_service_pb.js | 1 + .../engine_service_pb.d.ts | 11 + .../engine_service_pb.js | 50 +- .../src/engine/lib/constructor_calls.ts | 4 +- .../lib/kurtosis_context/kurtosis_context.ts | 55 +- .../src/engine/rest_api_bindings/types.d.ts | 7 + cli/cli/commands/enclave/add/add.go | 21 +- cli/cli/commands/import/import.go | 2 +- ...urtosis_backend_api_container_functions.go | 52 +- ...urtosis_backend_api_container_functions.go | 1 + .../metrics_reporting_kurtosis_backend.go | 2 + .../lib/backend_interface/kurtosis_backend.go | 1 + .../mock_kurtosis_backend.go | 33 +- .../api_container_launcher.go | 4 + core/scripts/build.sh | 24 +- core/server/Dockerfile.debug | 18 + core/server/scripts/_constants.env | 8 + core/server/scripts/build.sh | 84 ++- engine/scripts/build.sh | 2 +- .../engine/enclave_manager/enclave_creator.go | 5 + .../engine/enclave_manager/enclave_manager.go | 3 + .../engine/enclave_manager/enclave_pool.go | 8 +- .../server/engine_connect_server_service.go | 1 + .../engine/server/engine_rest_api_handler.go | 2 + internal_testsuites/typescript/yarn.lock | 474 +++++++-------- .../goland-apic-breakpoint.png | Bin 0 -> 44240 bytes .../goland-apic-debug-button.png | Bin 0 -> 12366 bytes scripts/build.sh | 4 +- scripts/port-forward-apic-debug.sh | 43 ++ 39 files changed, 1125 insertions(+), 624 deletions(-) create mode 100644 .run/APIC-remote-debug.run.xml create mode 100644 core/server/Dockerfile.debug create mode 100644 readme-static-files/goland-apic-breakpoint.png create mode 100644 readme-static-files/goland-apic-debug-button.png create mode 100755 scripts/port-forward-apic-debug.sh diff --git a/.run/APIC-remote-debug.run.xml b/.run/APIC-remote-debug.run.xml new file mode 100644 index 0000000000..33a5ae807f --- /dev/null +++ b/.run/APIC-remote-debug.run.xml @@ -0,0 +1,6 @@ + + + + diff --git a/README.md b/README.md index 97264e8b52..ad13bf1161 100644 --- a/README.md +++ b/README.md @@ -428,10 +428,10 @@ ktdev engine start --debug-mode 4. Then choose the "Engine-remote-debug" run configuration in the "run panel" 5. Press the "debug" button -6. Use the debug panel to inspect the variables value and continue with the debug flow - -7. Make a call to the engine's server (you can use the Kurtosis CLI or Postman) in order to reach out the breakpoint in the code -8. You can debug the CLI and the Kurtosis engine's server at the same time by running it with `ktdebug` instead of `ktdev` mentioned in a previous step, remember to run both remote debug configuration in the Goland IDE. +6. Make a call to the engine's server (you can use the Kurtosis CLI or Postman) in order to reach out the breakpoint in the code +7. Use the debug panel to inspect the variables value and continue with the debug flow + +8. You can debug the CLI and the Kurtosis engine's server at the same time by running it with `ktdebug` instead of `ktdev` mentioned in a previous step, remember to run both remote debug configurations in the Goland IDE. ```bash source ./scripts/set_kt_alias.sh ktdebug engine start @@ -453,6 +453,57 @@ scripts/port-forward-engine-debug.sh ktdev gateway ``` +For running Kurtosis APIC with Golang remote debug: +1. Run the main build script with the first argument `debug_mode` as true. This will generate a new Kurtosis APIC container image which will contain the `debug` suffix in the name. +```bash +scripts/build.sh true +``` +2. Add the breakpoint in the line where you want to stop the cursor. + +3. Run the Kurtosis engine in debug more or not depending on if you want to also debug the engine. +```bash +source ./scripts/set_kt_alias.sh +ktdev engine start --debug-mode + +OR + +ktdev engine start # you will have to build the engine in the regular way `engine/scripts/build.sh` if you choose this version +``` +4. Add a new enclave in debug mode with the `enclave add` command and passing the `debug-mode` flag. This will create a new APIC container with the debug server port bounded and waiting for a connection. +IMPORTANT: You can only run one enclave in debug mode so far, if you want to run another one it will fail due the debug port is already in use, +```bash +ktdev enclave add --debug-mode +``` +5. Then choose the "APIC-remote-debug" run configuration in the "run panel" +6. Press the "debug" button + +7. Find the APIC's GRPC server port in the host machine (you can check it in Docker Desktop or using the Docker CLI, it's the one bounded with the container's 7443 port) +8. Make a call to the APIC's server (you can use the Kurtosis CLI or Postman) in order to reach out the breakpoint in the code +9. Use the debug panel to inspect the variables value and continue with the debug flow + +10. You can debug the CLI, the Kurtosis engine's server and the Kurtosis APIC's server at the same time by running it with `ktdebug` instead of `ktdev` mentioned in a previous step, remember to run the three remote debug configurations in the Goland IDE. +```bash +source ./scripts/set_kt_alias.sh +ktdev engine start --debug-mode +ktdebug enclave add +``` + +Additional steps if you are debugging Kurtosis engine in K8s: + +1. Upload the APIC's image for debug to the K8s cluster +```bash +# for example: +k3d image load kurtosistech/core:5ec6eb-dirty-debug +``` +2. Run the port-forward script before pressing the debug button in Golang (in another terminal instance) to bind the host's port to the container's debug server port +```bash +scripts/port-forward-apic-debug.sh enclave-name +``` +3. Do not forget to run the Kurtosis gateway after calling the APIC's server (in another terminal instance also) +```bash +ktdev gateway +``` + diff --git a/api/golang/engine/kurtosis_engine_rpc_api_bindings/engine_service.pb.go b/api/golang/engine/kurtosis_engine_rpc_api_bindings/engine_service.pb.go index 13d42f6d3b..e15990f41e 100644 --- a/api/golang/engine/kurtosis_engine_rpc_api_bindings/engine_service.pb.go +++ b/api/golang/engine/kurtosis_engine_rpc_api_bindings/engine_service.pb.go @@ -309,6 +309,9 @@ type CreateEnclaveArgs struct { // The API container log level ApiContainerLogLevel *string `protobuf:"bytes,3,opt,name=api_container_log_level,json=apiContainerLogLevel,proto3,oneof" json:"api_container_log_level,omitempty"` Mode *EnclaveMode `protobuf:"varint,4,opt,name=mode,proto3,enum=engine_api.EnclaveMode,oneof" json:"mode,omitempty"` + // Whether the APIC's container should run with the debug server to receive a remote debug connection + // This is not an EnclaveMode because we will need to debug both current Modes (Test and Prod) + ShouldApicRunInDebugMode *bool `protobuf:"varint,5,opt,name=should_apic_run_in_debug_mode,json=shouldApicRunInDebugMode,proto3,oneof" json:"should_apic_run_in_debug_mode,omitempty"` } func (x *CreateEnclaveArgs) Reset() { @@ -371,6 +374,13 @@ func (x *CreateEnclaveArgs) GetMode() EnclaveMode { return EnclaveMode_TEST } +func (x *CreateEnclaveArgs) GetShouldApicRunInDebugMode() bool { + if x != nil && x.ShouldApicRunInDebugMode != nil { + return *x.ShouldApicRunInDebugMode + } + return false +} + type CreateEnclaveResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1375,7 +1385,7 @@ var file_engine_service_proto_rawDesc = []byte{ 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x22, 0xbd, 0x02, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x63, 0x6c, 0x61, + 0x22, 0xa5, 0x03, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x41, 0x72, 0x67, 0x73, 0x12, 0x26, 0x0a, 0x0c, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x3e, @@ -1389,282 +1399,288 @@ var file_engine_service_proto_rawDesc = []byte{ 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x30, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x4d, 0x6f, 0x64, - 0x65, 0x48, 0x03, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x88, 0x01, 0x01, 0x42, 0x0f, 0x0a, 0x0d, - 0x5f, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x1c, 0x0a, - 0x1a, 0x5f, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x61, 0x67, 0x42, 0x1a, 0x0a, 0x18, 0x5f, - 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x6c, 0x6f, - 0x67, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6d, 0x6f, 0x64, 0x65, - 0x22, 0x53, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x0c, 0x65, 0x6e, 0x63, - 0x6c, 0x61, 0x76, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x17, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x45, 0x6e, 0x63, - 0x6c, 0x61, 0x76, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, - 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0xcd, 0x01, 0x0a, 0x17, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, - 0x65, 0x41, 0x50, 0x49, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, - 0x6f, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x49, 0x64, 0x12, 0x2a, 0x0a, 0x11, 0x69, 0x70, 0x5f, 0x69, 0x6e, 0x73, 0x69, 0x64, - 0x65, 0x5f, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0f, 0x69, 0x70, 0x49, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, - 0x12, 0x37, 0x0a, 0x18, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x69, 0x6e, - 0x73, 0x69, 0x64, 0x65, 0x5f, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x15, 0x67, 0x72, 0x70, 0x63, 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x73, 0x69, - 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x62, 0x72, 0x69, - 0x64, 0x67, 0x65, 0x5f, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x49, 0x70, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x8b, 0x01, 0x0a, 0x22, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, - 0x65, 0x41, 0x50, 0x49, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x48, 0x6f, 0x73, - 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2b, 0x0a, 0x12, - 0x69, 0x70, 0x5f, 0x6f, 0x6e, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x63, 0x68, 0x69, - 0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x69, 0x70, 0x4f, 0x6e, 0x48, 0x6f, - 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x38, 0x0a, 0x19, 0x67, 0x72, 0x70, - 0x63, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6f, 0x6e, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x6d, - 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x67, 0x72, - 0x70, 0x63, 0x50, 0x6f, 0x72, 0x74, 0x4f, 0x6e, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, - 0x69, 0x6e, 0x65, 0x22, 0xcd, 0x04, 0x0a, 0x0b, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x49, - 0x6e, 0x66, 0x6f, 0x12, 0x21, 0x0a, 0x0c, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x5f, 0x75, - 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x6e, 0x63, 0x6c, 0x61, - 0x76, 0x65, 0x55, 0x75, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x68, - 0x6f, 0x72, 0x74, 0x65, 0x6e, 0x65, 0x64, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0d, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x65, 0x6e, 0x65, 0x64, 0x55, 0x75, 0x69, - 0x64, 0x12, 0x50, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x5f, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x65, - 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, - 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x57, 0x0a, 0x14, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x25, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x45, - 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x41, 0x50, 0x49, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x12, 0x61, 0x70, 0x69, 0x43, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x51, 0x0a, 0x12, - 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x6e, - 0x66, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, - 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x41, 0x50, 0x49, - 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x10, 0x61, - 0x70, 0x69, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, - 0x74, 0x0a, 0x1f, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x6e, - 0x66, 0x6f, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, - 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x41, 0x50, 0x49, - 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x63, - 0x68, 0x69, 0x6e, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x1b, 0x61, 0x70, 0x69, 0x43, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, - 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3f, 0x0a, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x09, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, - 0x69, 0x2e, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, - 0x6f, 0x64, 0x65, 0x22, 0xc3, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x63, 0x6c, 0x61, - 0x76, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x0c, 0x65, - 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x30, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x47, - 0x65, 0x74, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x2e, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x0b, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x49, 0x6e, 0x66, 0x6f, - 0x1a, 0x57, 0x0a, 0x10, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, - 0x70, 0x69, 0x2e, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x72, 0x0a, 0x12, 0x45, 0x6e, 0x63, - 0x6c, 0x61, 0x76, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x12, - 0x21, 0x0a, 0x0c, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x55, 0x75, - 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x65, - 0x6e, 0x65, 0x64, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, - 0x73, 0x68, 0x6f, 0x72, 0x74, 0x65, 0x6e, 0x65, 0x64, 0x55, 0x75, 0x69, 0x64, 0x22, 0x7c, 0x0a, - 0x32, 0x47, 0x65, 0x74, 0x45, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x41, 0x6e, 0x64, 0x48, - 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, - 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x0e, 0x61, 0x6c, 0x6c, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x66, 0x69, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x6e, - 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, - 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x52, 0x0e, 0x61, 0x6c, 0x6c, - 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x22, 0x40, 0x0a, 0x0f, 0x53, - 0x74, 0x6f, 0x70, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x41, 0x72, 0x67, 0x73, 0x12, 0x2d, - 0x0a, 0x12, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x65, 0x6e, 0x63, 0x6c, - 0x61, 0x76, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x22, 0x43, 0x0a, - 0x12, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x41, - 0x72, 0x67, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x5f, 0x69, - 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x11, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, - 0x65, 0x72, 0x22, 0x4f, 0x0a, 0x09, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x41, 0x72, 0x67, 0x73, 0x12, - 0x2d, 0x0a, 0x10, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x6e, 0x5f, - 0x61, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x0e, 0x73, 0x68, 0x6f, - 0x75, 0x6c, 0x64, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x41, 0x6c, 0x6c, 0x88, 0x01, 0x01, 0x42, 0x13, - 0x0a, 0x11, 0x5f, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x6e, 0x5f, - 0x61, 0x6c, 0x6c, 0x22, 0x3c, 0x0a, 0x12, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x4e, 0x61, - 0x6d, 0x65, 0x41, 0x6e, 0x64, 0x55, 0x75, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, - 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, - 0x64, 0x22, 0x73, 0x0a, 0x0d, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x62, 0x0a, 0x1e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x5f, 0x65, 0x6e, - 0x63, 0x6c, 0x61, 0x76, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x75, - 0x75, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x6e, 0x67, - 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x4e, - 0x61, 0x6d, 0x65, 0x41, 0x6e, 0x64, 0x55, 0x75, 0x69, 0x64, 0x52, 0x1a, 0x72, 0x65, 0x6d, 0x6f, - 0x76, 0x65, 0x64, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x41, 0x6e, - 0x64, 0x55, 0x75, 0x69, 0x64, 0x73, 0x22, 0xe2, 0x03, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x41, 0x72, 0x67, 0x73, 0x12, 0x2d, 0x0a, - 0x12, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, - 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x65, 0x6e, 0x63, 0x6c, 0x61, - 0x76, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x5c, 0x0a, 0x10, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x5f, 0x73, 0x65, 0x74, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, - 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x6f, - 0x67, 0x73, 0x41, 0x72, 0x67, 0x73, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x75, - 0x69, 0x64, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x55, 0x75, 0x69, 0x64, 0x53, 0x65, 0x74, 0x12, 0x24, 0x0a, 0x0b, 0x66, 0x6f, - 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, - 0x00, 0x52, 0x0a, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x4c, 0x6f, 0x67, 0x73, 0x88, 0x01, 0x01, - 0x12, 0x4a, 0x0a, 0x13, 0x63, 0x6f, 0x6e, 0x6a, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, - 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, - 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x6f, 0x67, 0x4c, 0x69, - 0x6e, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x6a, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x2b, 0x0a, 0x0f, - 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x08, 0x48, 0x01, 0x52, 0x0d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x41, - 0x6c, 0x6c, 0x4c, 0x6f, 0x67, 0x73, 0x88, 0x01, 0x01, 0x12, 0x27, 0x0a, 0x0d, 0x6e, 0x75, 0x6d, - 0x5f, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, - 0x48, 0x02, 0x52, 0x0b, 0x6e, 0x75, 0x6d, 0x4c, 0x6f, 0x67, 0x4c, 0x69, 0x6e, 0x65, 0x73, 0x88, - 0x01, 0x01, 0x1a, 0x41, 0x0a, 0x13, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x75, 0x69, - 0x64, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, - 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, - 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x6e, 0x75, - 0x6d, 0x5f, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x22, 0xc4, 0x03, 0x0a, 0x16, - 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x80, 0x01, 0x0a, 0x1c, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, - 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x42, 0x79, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x75, 0x69, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x18, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x42, 0x79, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x75, 0x69, 0x64, 0x12, 0x7a, 0x0a, 0x1a, 0x6e, 0x6f, 0x74, - 0x5f, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x75, - 0x75, 0x69, 0x64, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, - 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2e, 0x4e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x55, 0x75, 0x69, 0x64, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x16, 0x6e, - 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x75, - 0x69, 0x64, 0x53, 0x65, 0x74, 0x1a, 0x60, 0x0a, 0x1d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x4c, 0x6f, 0x67, 0x73, 0x42, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x75, 0x69, - 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, - 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x6f, 0x67, 0x4c, 0x69, 0x6e, 0x65, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x49, 0x0a, 0x1b, 0x4e, 0x6f, 0x74, 0x46, 0x6f, - 0x75, 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x75, 0x69, 0x64, 0x53, 0x65, - 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x22, 0x57, 0x0a, 0x07, 0x4c, 0x6f, 0x67, 0x4c, 0x69, 0x6e, 0x65, 0x12, 0x12, 0x0a, - 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, - 0x65, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, + 0x65, 0x48, 0x03, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x88, 0x01, 0x01, 0x12, 0x44, 0x0a, 0x1d, + 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x5f, 0x61, 0x70, 0x69, 0x63, 0x5f, 0x72, 0x75, 0x6e, 0x5f, + 0x69, 0x6e, 0x5f, 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x08, 0x48, 0x04, 0x52, 0x18, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x41, 0x70, 0x69, + 0x63, 0x52, 0x75, 0x6e, 0x49, 0x6e, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x88, + 0x01, 0x01, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x42, 0x1c, 0x0a, 0x1a, 0x5f, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x61, + 0x67, 0x42, 0x1a, 0x0a, 0x18, 0x5f, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x42, 0x07, 0x0a, + 0x05, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x42, 0x20, 0x0a, 0x1e, 0x5f, 0x73, 0x68, 0x6f, 0x75, 0x6c, + 0x64, 0x5f, 0x61, 0x70, 0x69, 0x63, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x69, 0x6e, 0x5f, 0x64, 0x65, + 0x62, 0x75, 0x67, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0x53, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x3a, 0x0a, 0x0c, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x5f, 0x69, 0x6e, 0x66, + 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, + 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x0b, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0xcd, 0x01, + 0x0a, 0x17, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x41, 0x50, 0x49, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x2a, 0x0a, 0x11, + 0x69, 0x70, 0x5f, 0x69, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x5f, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x69, 0x70, 0x49, 0x6e, 0x73, 0x69, 0x64, + 0x65, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x12, 0x37, 0x0a, 0x18, 0x67, 0x72, 0x70, 0x63, + 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x69, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x5f, 0x65, 0x6e, 0x63, + 0x6c, 0x61, 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x67, 0x72, 0x70, 0x63, + 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, + 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x5f, 0x69, 0x70, 0x5f, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x62, 0x72, + 0x69, 0x64, 0x67, 0x65, 0x49, 0x70, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x8b, 0x01, + 0x0a, 0x22, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x41, 0x50, 0x49, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, + 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2b, 0x0a, 0x12, 0x69, 0x70, 0x5f, 0x6f, 0x6e, 0x5f, 0x68, 0x6f, + 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0f, 0x69, 0x70, 0x4f, 0x6e, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, + 0x65, 0x12, 0x38, 0x0a, 0x19, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6f, + 0x6e, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x67, 0x72, 0x70, 0x63, 0x50, 0x6f, 0x72, 0x74, 0x4f, 0x6e, + 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x22, 0xcd, 0x04, 0x0a, 0x0b, + 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x21, 0x0a, 0x0c, 0x65, + 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x55, 0x75, 0x69, 0x64, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x65, 0x6e, 0x65, 0x64, 0x5f, + 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x68, 0x6f, 0x72, + 0x74, 0x65, 0x6e, 0x65, 0x64, 0x55, 0x75, 0x69, 0x64, 0x12, 0x50, 0x0a, 0x11, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, + 0x69, 0x2e, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x57, 0x0a, 0x14, 0x61, + 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x65, 0x6e, 0x67, 0x69, + 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x41, 0x50, + 0x49, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x12, 0x61, 0x70, 0x69, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x51, 0x0a, 0x12, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x23, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x45, 0x6e, + 0x63, 0x6c, 0x61, 0x76, 0x65, 0x41, 0x50, 0x49, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x10, 0x61, 0x70, 0x69, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x74, 0x0a, 0x1f, 0x61, 0x70, 0x69, 0x5f, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x6d, 0x61, + 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x2e, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x45, 0x6e, + 0x63, 0x6c, 0x61, 0x76, 0x65, 0x41, 0x50, 0x49, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x1b, 0x61, 0x70, 0x69, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x48, 0x6f, + 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3f, 0x0a, + 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x6b, 0x0a, 0x0d, 0x4c, - 0x6f, 0x67, 0x4c, 0x69, 0x6e, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x37, 0x0a, 0x08, - 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, - 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x6f, 0x67, 0x4c, - 0x69, 0x6e, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x08, 0x6f, 0x70, 0x65, - 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, - 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x65, 0x78, - 0x74, 0x50, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x2a, 0x27, 0x0a, 0x0b, 0x45, 0x6e, 0x63, 0x6c, - 0x61, 0x76, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x54, 0x45, 0x53, 0x54, 0x10, - 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x4f, 0x44, 0x55, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, - 0x01, 0x2a, 0x86, 0x01, 0x0a, 0x17, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x43, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x0a, - 0x1d, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x45, 0x4d, 0x50, 0x54, 0x59, 0x10, 0x00, - 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x52, 0x55, 0x4e, 0x4e, - 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, + 0x52, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2b, + 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x65, + 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, + 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0xc3, 0x01, 0x0a, 0x13, + 0x47, 0x65, 0x74, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x0c, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x5f, 0x69, + 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x65, 0x6e, 0x67, 0x69, + 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x45, 0x6e, 0x63, 0x6c, 0x61, + 0x76, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x65, 0x6e, 0x63, + 0x6c, 0x61, 0x76, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x57, 0x0a, 0x10, 0x45, 0x6e, 0x63, 0x6c, + 0x61, 0x76, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x45, 0x6e, 0x63, 0x6c, 0x61, + 0x76, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0x72, 0x0a, 0x12, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x65, 0x6e, 0x63, 0x6c, 0x61, + 0x76, 0x65, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, + 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x55, 0x75, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, + 0x0a, 0x0e, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x65, 0x6e, 0x65, 0x64, 0x5f, 0x75, 0x75, 0x69, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x65, 0x6e, 0x65, + 0x64, 0x55, 0x75, 0x69, 0x64, 0x22, 0x7c, 0x0a, 0x32, 0x47, 0x65, 0x74, 0x45, 0x78, 0x69, 0x73, + 0x74, 0x69, 0x6e, 0x67, 0x41, 0x6e, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, + 0x6c, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, + 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x0e, 0x61, + 0x6c, 0x6c, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, + 0x2e, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, + 0x65, 0x72, 0x73, 0x52, 0x0e, 0x61, 0x6c, 0x6c, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, + 0x65, 0x72, 0x73, 0x22, 0x40, 0x0a, 0x0f, 0x53, 0x74, 0x6f, 0x70, 0x45, 0x6e, 0x63, 0x6c, 0x61, + 0x76, 0x65, 0x41, 0x72, 0x67, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, + 0x65, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x11, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x66, 0x69, 0x65, 0x72, 0x22, 0x43, 0x0a, 0x12, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, + 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x41, 0x72, 0x67, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x65, + 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, + 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x22, 0x4f, 0x0a, 0x09, 0x43, 0x6c, + 0x65, 0x61, 0x6e, 0x41, 0x72, 0x67, 0x73, 0x12, 0x2d, 0x0a, 0x10, 0x73, 0x68, 0x6f, 0x75, 0x6c, + 0x64, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x6e, 0x5f, 0x61, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x48, 0x00, 0x52, 0x0e, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x43, 0x6c, 0x65, 0x61, 0x6e, + 0x41, 0x6c, 0x6c, 0x88, 0x01, 0x01, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x73, 0x68, 0x6f, 0x75, 0x6c, + 0x64, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x6e, 0x5f, 0x61, 0x6c, 0x6c, 0x22, 0x3c, 0x0a, 0x12, 0x45, + 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x41, 0x6e, 0x64, 0x55, 0x75, 0x69, + 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0x73, 0x0a, 0x0d, 0x43, 0x6c, 0x65, + 0x61, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x1e, 0x72, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x5f, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, + 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x41, 0x6e, 0x64, 0x55, 0x75, + 0x69, 0x64, 0x52, 0x1a, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x45, 0x6e, 0x63, 0x6c, 0x61, + 0x76, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x41, 0x6e, 0x64, 0x55, 0x75, 0x69, 0x64, 0x73, 0x22, 0xe2, + 0x03, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x67, + 0x73, 0x41, 0x72, 0x67, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, + 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x11, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x66, 0x69, 0x65, 0x72, 0x12, 0x5c, 0x0a, 0x10, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, + 0x75, 0x75, 0x69, 0x64, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, + 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x41, 0x72, 0x67, 0x73, 0x2e, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x75, 0x69, 0x64, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x75, 0x69, 0x64, 0x53, + 0x65, 0x74, 0x12, 0x24, 0x0a, 0x0b, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x6c, 0x6f, 0x67, + 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x0a, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, + 0x77, 0x4c, 0x6f, 0x67, 0x73, 0x88, 0x01, 0x01, 0x12, 0x4a, 0x0a, 0x13, 0x63, 0x6f, 0x6e, 0x6a, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, + 0x70, 0x69, 0x2e, 0x4c, 0x6f, 0x67, 0x4c, 0x69, 0x6e, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x6a, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x76, 0x65, 0x46, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x73, 0x12, 0x2b, 0x0a, 0x0f, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x61, + 0x6c, 0x6c, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x48, 0x01, 0x52, + 0x0d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x41, 0x6c, 0x6c, 0x4c, 0x6f, 0x67, 0x73, 0x88, 0x01, + 0x01, 0x12, 0x27, 0x0a, 0x0d, 0x6e, 0x75, 0x6d, 0x5f, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x69, 0x6e, + 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x02, 0x52, 0x0b, 0x6e, 0x75, 0x6d, 0x4c, + 0x6f, 0x67, 0x4c, 0x69, 0x6e, 0x65, 0x73, 0x88, 0x01, 0x01, 0x1a, 0x41, 0x0a, 0x13, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x75, 0x69, 0x64, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x0e, 0x0a, + 0x0c, 0x5f, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x42, 0x12, 0x0a, + 0x10, 0x5f, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x6c, 0x6f, 0x67, + 0x73, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x6e, 0x75, 0x6d, 0x5f, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x69, + 0x6e, 0x65, 0x73, 0x22, 0xc4, 0x03, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x80, + 0x01, 0x0a, 0x1c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x5f, + 0x62, 0x79, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, + 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x67, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x42, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x75, + 0x69, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x18, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x4c, 0x6f, 0x67, 0x73, 0x42, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x75, 0x69, + 0x64, 0x12, 0x7a, 0x0a, 0x1a, 0x6e, 0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x5f, 0x73, 0x65, 0x74, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, + 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x67, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4e, 0x6f, 0x74, 0x46, 0x6f, 0x75, + 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x75, 0x69, 0x64, 0x53, 0x65, 0x74, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x16, 0x6e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x75, 0x69, 0x64, 0x53, 0x65, 0x74, 0x1a, 0x60, 0x0a, + 0x1d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x42, 0x79, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x75, 0x69, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x13, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x6f, 0x67, + 0x4c, 0x69, 0x6e, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, + 0x49, 0x0a, 0x1b, 0x4e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x55, 0x75, 0x69, 0x64, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x57, 0x0a, 0x07, 0x4c, 0x6f, + 0x67, 0x4c, 0x69, 0x6e, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x22, 0x6b, 0x0a, 0x0d, 0x4c, 0x6f, 0x67, 0x4c, 0x69, 0x6e, 0x65, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x12, 0x37, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, + 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x6f, 0x67, 0x4c, 0x69, 0x6e, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x6f, 0x72, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x21, 0x0a, + 0x0c, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x65, 0x78, 0x74, 0x50, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, + 0x2a, 0x27, 0x0a, 0x0b, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x12, + 0x08, 0x0a, 0x04, 0x54, 0x45, 0x53, 0x54, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x4f, + 0x44, 0x55, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x2a, 0x86, 0x01, 0x0a, 0x17, 0x45, 0x6e, + 0x63, 0x6c, 0x61, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x50, 0x45, 0x44, 0x10, 0x02, 0x2a, 0x94, 0x01, 0x0a, 0x19, 0x45, - 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x41, 0x50, 0x49, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x29, 0x0a, 0x25, 0x45, 0x6e, 0x63, 0x6c, - 0x61, 0x76, 0x65, 0x41, 0x50, 0x49, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x58, 0x49, 0x53, 0x54, 0x45, 0x4e, - 0x54, 0x10, 0x00, 0x12, 0x25, 0x0a, 0x21, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x41, 0x50, + 0x5f, 0x45, 0x4d, 0x50, 0x54, 0x59, 0x10, 0x00, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x6e, 0x63, 0x6c, + 0x61, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x5f, 0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x23, 0x0a, + 0x1f, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x50, 0x45, 0x44, + 0x10, 0x02, 0x2a, 0x94, 0x01, 0x0a, 0x19, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x41, 0x50, 0x49, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x5f, 0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x25, 0x0a, 0x21, 0x45, 0x6e, - 0x63, 0x6c, 0x61, 0x76, 0x65, 0x41, 0x50, 0x49, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x50, 0x45, 0x44, 0x10, - 0x02, 0x2a, 0xc3, 0x01, 0x0a, 0x0f, 0x4c, 0x6f, 0x67, 0x4c, 0x69, 0x6e, 0x65, 0x4f, 0x70, 0x65, - 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x25, 0x0a, 0x21, 0x4c, 0x6f, 0x67, 0x4c, 0x69, 0x6e, 0x65, - 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x44, 0x4f, 0x45, 0x53, 0x5f, 0x43, 0x4f, - 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x45, 0x58, 0x54, 0x10, 0x00, 0x12, 0x29, 0x0a, 0x25, - 0x4c, 0x6f, 0x67, 0x4c, 0x69, 0x6e, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, - 0x44, 0x4f, 0x45, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, - 0x5f, 0x54, 0x45, 0x58, 0x54, 0x10, 0x01, 0x12, 0x2c, 0x0a, 0x28, 0x4c, 0x6f, 0x67, 0x4c, 0x69, - 0x6e, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x44, 0x4f, 0x45, 0x53, 0x5f, - 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x52, 0x45, - 0x47, 0x45, 0x58, 0x10, 0x02, 0x12, 0x30, 0x0a, 0x2c, 0x4c, 0x6f, 0x67, 0x4c, 0x69, 0x6e, 0x65, - 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x44, 0x4f, 0x45, 0x53, 0x5f, 0x4e, 0x4f, - 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, - 0x52, 0x45, 0x47, 0x45, 0x58, 0x10, 0x03, 0x32, 0xae, 0x05, 0x0a, 0x0d, 0x45, 0x6e, 0x67, 0x69, - 0x6e, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4c, 0x0a, 0x0d, 0x47, 0x65, 0x74, - 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x1a, 0x21, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, - 0x47, 0x65, 0x74, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x12, 0x1d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, - 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x63, 0x6c, - 0x61, 0x76, 0x65, 0x41, 0x72, 0x67, 0x73, 0x1a, 0x21, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, - 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x63, 0x6c, 0x61, - 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x0b, - 0x47, 0x65, 0x74, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x1a, 0x1f, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, - 0x2e, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x86, 0x01, 0x0a, 0x2a, 0x47, 0x65, 0x74, 0x45, 0x78, - 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x41, 0x6e, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, - 0x63, 0x61, 0x6c, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x66, 0x69, 0x65, 0x72, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x3e, 0x2e, - 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, - 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x41, 0x6e, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, - 0x63, 0x61, 0x6c, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x66, 0x69, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x44, 0x0a, 0x0b, 0x53, 0x74, 0x6f, 0x70, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x12, 0x1b, - 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x6f, 0x70, - 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x41, 0x72, 0x67, 0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x4a, 0x0a, 0x0e, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, - 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x12, 0x1e, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, - 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x45, 0x6e, 0x63, 0x6c, - 0x61, 0x76, 0x65, 0x41, 0x72, 0x67, 0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, - 0x00, 0x12, 0x3b, 0x0a, 0x05, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x12, 0x15, 0x2e, 0x65, 0x6e, 0x67, - 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x41, 0x72, 0x67, - 0x73, 0x1a, 0x19, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x43, - 0x6c, 0x65, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, - 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x67, 0x73, - 0x12, 0x1e, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, - 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x41, 0x72, 0x67, 0x73, - 0x1a, 0x22, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, - 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x42, 0x56, 0x5a, 0x54, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x75, 0x72, 0x74, 0x6f, 0x73, 0x69, 0x73, 0x2d, - 0x74, 0x65, 0x63, 0x68, 0x2f, 0x6b, 0x75, 0x72, 0x74, 0x6f, 0x73, 0x69, 0x73, 0x2f, 0x61, 0x70, - 0x69, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2f, - 0x6b, 0x75, 0x72, 0x74, 0x6f, 0x73, 0x69, 0x73, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, - 0x72, 0x70, 0x63, 0x5f, 0x61, 0x70, 0x69, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x29, 0x0a, 0x25, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x41, 0x50, 0x49, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x4e, 0x4f, + 0x4e, 0x45, 0x58, 0x49, 0x53, 0x54, 0x45, 0x4e, 0x54, 0x10, 0x00, 0x12, 0x25, 0x0a, 0x21, 0x45, + 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x41, 0x50, 0x49, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, + 0x10, 0x01, 0x12, 0x25, 0x0a, 0x21, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x41, 0x50, 0x49, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, + 0x53, 0x54, 0x4f, 0x50, 0x50, 0x45, 0x44, 0x10, 0x02, 0x2a, 0xc3, 0x01, 0x0a, 0x0f, 0x4c, 0x6f, + 0x67, 0x4c, 0x69, 0x6e, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x25, 0x0a, + 0x21, 0x4c, 0x6f, 0x67, 0x4c, 0x69, 0x6e, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x5f, 0x44, 0x4f, 0x45, 0x53, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x45, + 0x58, 0x54, 0x10, 0x00, 0x12, 0x29, 0x0a, 0x25, 0x4c, 0x6f, 0x67, 0x4c, 0x69, 0x6e, 0x65, 0x4f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x44, 0x4f, 0x45, 0x53, 0x5f, 0x4e, 0x4f, 0x54, + 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x45, 0x58, 0x54, 0x10, 0x01, 0x12, + 0x2c, 0x0a, 0x28, 0x4c, 0x6f, 0x67, 0x4c, 0x69, 0x6e, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x6f, 0x72, 0x5f, 0x44, 0x4f, 0x45, 0x53, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x5f, + 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x52, 0x45, 0x47, 0x45, 0x58, 0x10, 0x02, 0x12, 0x30, 0x0a, + 0x2c, 0x4c, 0x6f, 0x67, 0x4c, 0x69, 0x6e, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x5f, 0x44, 0x4f, 0x45, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, + 0x4e, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x52, 0x45, 0x47, 0x45, 0x58, 0x10, 0x03, 0x32, + 0xae, 0x05, 0x0a, 0x0d, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x4c, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x49, 0x6e, + 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x21, 0x2e, 0x65, 0x6e, 0x67, + 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x53, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, + 0x12, 0x1d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x41, 0x72, 0x67, 0x73, 0x1a, + 0x21, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x63, 0x6c, 0x61, + 0x76, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1f, 0x2e, 0x65, 0x6e, + 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x63, 0x6c, + 0x61, 0x76, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x86, + 0x01, 0x0a, 0x2a, 0x47, 0x65, 0x74, 0x45, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x41, 0x6e, + 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x45, 0x6e, 0x63, 0x6c, 0x61, + 0x76, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x12, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x3e, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, + 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x41, 0x6e, + 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x45, 0x6e, 0x63, 0x6c, 0x61, + 0x76, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x0b, 0x53, 0x74, 0x6f, 0x70, 0x45, + 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x12, 0x1b, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, + 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x41, + 0x72, 0x67, 0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x4a, 0x0a, + 0x0e, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x12, + 0x1e, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x73, + 0x74, 0x72, 0x6f, 0x79, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x41, 0x72, 0x67, 0x73, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x05, 0x43, 0x6c, 0x65, + 0x61, 0x6e, 0x12, 0x15, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, + 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x41, 0x72, 0x67, 0x73, 0x1a, 0x19, 0x2e, 0x65, 0x6e, 0x67, 0x69, + 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x1e, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x4c, 0x6f, 0x67, 0x73, 0x41, 0x72, 0x67, 0x73, 0x1a, 0x22, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, + 0x42, 0x56, 0x5a, 0x54, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, + 0x75, 0x72, 0x74, 0x6f, 0x73, 0x69, 0x73, 0x2d, 0x74, 0x65, 0x63, 0x68, 0x2f, 0x6b, 0x75, 0x72, + 0x74, 0x6f, 0x73, 0x69, 0x73, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, + 0x2f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2f, 0x6b, 0x75, 0x72, 0x74, 0x6f, 0x73, 0x69, 0x73, + 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x72, 0x70, 0x63, 0x5f, 0x61, 0x70, 0x69, 0x5f, + 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/golang/engine/lib/kurtosis_context/kurtosis_context.go b/api/golang/engine/lib/kurtosis_context/kurtosis_context.go index 7c25447eba..ed94156386 100644 --- a/api/golang/engine/lib/kurtosis_context/kurtosis_context.go +++ b/api/golang/engine/lib/kurtosis_context/kurtosis_context.go @@ -39,6 +39,9 @@ const ( validUuidMatchesAllowed = 1 portalIsRequired = true + + defaultShouldAPICRunInDebugMode = false + runAPICInDebugMode = true ) var ( @@ -105,10 +108,7 @@ func NewKurtosisContextFromLocalEngine() (*KurtosisContext, error) { } // Docs available at https://docs.kurtosis.com/sdk#createenclaveenclaveid-enclaveid-boolean-issubnetworkingenabled---enclavecontextenclavecontext-enclavecontext -func (kurtosisCtx *KurtosisContext) CreateEnclave( - ctx context.Context, - enclaveName string, -) (*enclaves.EnclaveContext, error) { +func (kurtosisCtx *KurtosisContext) CreateEnclave(ctx context.Context, enclaveName string) (*enclaves.EnclaveContext, error) { createEnclaveArgs := newCreateEnclaveArgsWithDefaultValues(enclaveName) @@ -125,12 +125,29 @@ func (kurtosisCtx *KurtosisContext) CreateEnclave( return enclaveContext, nil } -// Docs available at https://docs.kurtosis.com/sdk#createenclaveenclaveid-enclaveid-boolean-issubnetworkingenabled---enclavecontextenclavecontext-enclavecontext -func (kurtosisCtx *KurtosisContext) CreateProductionEnclave( +func (kurtosisCtx *KurtosisContext) CreateEnclaveWithDebugEnabled( ctx context.Context, enclaveName string, ) (*enclaves.EnclaveContext, error) { + createEnclaveArgs := newCreateEnclaveArgsWithDefaultValuesForDebugging(enclaveName) + + response, err := kurtosisCtx.engineClient.CreateEnclave(ctx, createEnclaveArgs) + if err != nil { + return nil, stacktrace.Propagate(err, "An error occurred creating an enclave with name '%v'", enclaveName) + } + + enclaveContext, err := newEnclaveContextFromEnclaveInfo(ctx, kurtosisCtx.portalClient, response.EnclaveInfo) + if err != nil { + return nil, stacktrace.Propagate(err, "An error occurred creating an enclave context from a newly-created enclave; this should never happen") + } + + return enclaveContext, nil +} + +// Docs available at https://docs.kurtosis.com/sdk#createenclaveenclaveid-enclaveid-boolean-issubnetworkingenabled---enclavecontextenclavecontext-enclavecontext +func (kurtosisCtx *KurtosisContext) CreateProductionEnclave(ctx context.Context, enclaveName string) (*enclaves.EnclaveContext, error) { + createEnclaveArgs := newCreateProductionEnclaveWithDefaultValues(enclaveName) response, err := kurtosisCtx.engineClient.CreateEnclave(ctx, createEnclaveArgs) @@ -146,6 +163,23 @@ func (kurtosisCtx *KurtosisContext) CreateProductionEnclave( return enclaveContext, nil } +func (kurtosisCtx *KurtosisContext) CreateProductionEnclaveWithDebugEnabled(ctx context.Context, enclaveName string) (*enclaves.EnclaveContext, error) { + + createEnclaveArgs := newCreateProductionEnclaveWithDefaultValuesForDebugging(enclaveName) + + response, err := kurtosisCtx.engineClient.CreateEnclave(ctx, createEnclaveArgs) + if err != nil { + return nil, stacktrace.Propagate(err, "An error occurred creating an enclave with name '%v'", enclaveName) + } + + enclaveContext, err := newEnclaveContextFromEnclaveInfo(ctx, kurtosisCtx.portalClient, response.EnclaveInfo) + if err != nil { + return nil, stacktrace.Propagate(err, "An error occurred creating an enclave context from a newly-created enclave; this should never happen") + } + + return enclaveContext, nil +} + // Docs available at https://docs.kurtosis.com/sdk/#getenclavecontextstring-enclaveidentifier---enclavecontextenclavecontext-enclavecontext func (kurtosisCtx *KurtosisContext) GetEnclaveContext(ctx context.Context, enclaveIdentifier string) (*enclaves.EnclaveContext, error) { enclaveInfo, err := kurtosisCtx.GetEnclave(ctx, enclaveIdentifier) @@ -594,12 +628,32 @@ func newCreateEnclaveArgsWithDefaultValues(enclaveName string) *kurtosis_engine_ defaultApiContainerVersionTag := defaultApiContainerVersionTagStr defaultApiContainerLogLevel := defaultApiContainerLogLevelStr defaultEnclaveMode := kurtosis_engine_rpc_api_bindings.EnclaveMode_TEST + shouldApicRunInDebugMode := defaultShouldAPICRunInDebugMode createEnclaveArgs := &kurtosis_engine_rpc_api_bindings.CreateEnclaveArgs{ - EnclaveName: &enclaveName, - ApiContainerVersionTag: &defaultApiContainerVersionTag, - ApiContainerLogLevel: &defaultApiContainerLogLevel, - Mode: &defaultEnclaveMode, + EnclaveName: &enclaveName, + ApiContainerVersionTag: &defaultApiContainerVersionTag, + ApiContainerLogLevel: &defaultApiContainerLogLevel, + Mode: &defaultEnclaveMode, + ShouldApicRunInDebugMode: &shouldApicRunInDebugMode, + } + + return createEnclaveArgs +} + +func newCreateEnclaveArgsWithDefaultValuesForDebugging(enclaveName string) *kurtosis_engine_rpc_api_bindings.CreateEnclaveArgs { + + defaultApiContainerVersionTag := defaultApiContainerVersionTagStr + defaultApiContainerLogLevel := defaultApiContainerLogLevelStr + defaultEnclaveMode := kurtosis_engine_rpc_api_bindings.EnclaveMode_TEST + shouldApicRunInDebugMode := runAPICInDebugMode + + createEnclaveArgs := &kurtosis_engine_rpc_api_bindings.CreateEnclaveArgs{ + EnclaveName: &enclaveName, + ApiContainerVersionTag: &defaultApiContainerVersionTag, + ApiContainerLogLevel: &defaultApiContainerLogLevel, + Mode: &defaultEnclaveMode, + ShouldApicRunInDebugMode: &shouldApicRunInDebugMode, } return createEnclaveArgs @@ -610,12 +664,32 @@ func newCreateProductionEnclaveWithDefaultValues(enclaveName string) *kurtosis_e defaultApiContainerVersionTag := defaultApiContainerVersionTagStr defaultApiContainerLogLevel := defaultApiContainerLogLevelStr defaultEnclaveMode := kurtosis_engine_rpc_api_bindings.EnclaveMode_PRODUCTION + shouldApicRunInDebugMode := defaultShouldAPICRunInDebugMode + + createEnclaveArgs := &kurtosis_engine_rpc_api_bindings.CreateEnclaveArgs{ + EnclaveName: &enclaveName, + ApiContainerVersionTag: &defaultApiContainerVersionTag, + ApiContainerLogLevel: &defaultApiContainerLogLevel, + Mode: &defaultEnclaveMode, + ShouldApicRunInDebugMode: &shouldApicRunInDebugMode, + } + + return createEnclaveArgs +} + +func newCreateProductionEnclaveWithDefaultValuesForDebugging(enclaveName string) *kurtosis_engine_rpc_api_bindings.CreateEnclaveArgs { + + defaultApiContainerVersionTag := defaultApiContainerVersionTagStr + defaultApiContainerLogLevel := defaultApiContainerLogLevelStr + defaultEnclaveMode := kurtosis_engine_rpc_api_bindings.EnclaveMode_PRODUCTION + shouldApicRunInDebugMode := runAPICInDebugMode createEnclaveArgs := &kurtosis_engine_rpc_api_bindings.CreateEnclaveArgs{ - EnclaveName: &enclaveName, - ApiContainerVersionTag: &defaultApiContainerVersionTag, - ApiContainerLogLevel: &defaultApiContainerLogLevel, - Mode: &defaultEnclaveMode, + EnclaveName: &enclaveName, + ApiContainerVersionTag: &defaultApiContainerVersionTag, + ApiContainerLogLevel: &defaultApiContainerLogLevel, + Mode: &defaultEnclaveMode, + ShouldApicRunInDebugMode: &shouldApicRunInDebugMode, } return createEnclaveArgs diff --git a/api/golang/http_rest/api_types/api_types.gen.go b/api/golang/http_rest/api_types/api_types.gen.go index cf318293f4..877ee1b211 100644 --- a/api/golang/http_rest/api_types/api_types.gen.go +++ b/api/golang/http_rest/api_types/api_types.gen.go @@ -11,6 +11,12 @@ import ( openapi_types "github.com/oapi-codegen/runtime/types" ) +// Defines values for ApiContainerDebugMode. +const ( + False ApiContainerDebugMode = false + True ApiContainerDebugMode = true +) + // Defines values for ApiContainerStatus. const ( ApiContainerStatusNONEXISTENT ApiContainerStatus = "NON_EXISTENT" @@ -101,6 +107,9 @@ const ( UDP TransportProtocol = "UDP" ) +// ApiContainerDebugMode defines model for ApiContainerDebugMode. +type ApiContainerDebugMode bool + // ApiContainerStatus defines model for ApiContainerStatus. type ApiContainerStatus string @@ -137,10 +146,11 @@ type ContainerStatus string // CreateEnclave defines model for CreateEnclave. type CreateEnclave struct { // ApiContainerLogLevel Enclave log level, defaults to INFO - ApiContainerLogLevel *string `json:"api_container_log_level,omitempty"` - ApiContainerVersionTag string `json:"api_container_version_tag"` - EnclaveName string `json:"enclave_name"` - Mode *EnclaveMode `json:"mode,omitempty"` + ApiContainerLogLevel *string `json:"api_container_log_level,omitempty"` + ApiContainerVersionTag string `json:"api_container_version_tag"` + EnclaveName string `json:"enclave_name"` + Mode *EnclaveMode `json:"mode,omitempty"` + ShouldApicRunInDebugMode *ApiContainerDebugMode `json:"should_apic_run_in_debug_mode,omitempty"` } // DeletionSummary defines model for DeletionSummary. diff --git a/api/golang/http_rest/server/engine_rest_api/engine_server.gen.go b/api/golang/http_rest/server/engine_rest_api/engine_server.gen.go index b0a2ed1e40..032f122253 100644 --- a/api/golang/http_rest/server/engine_rest_api/engine_server.gen.go +++ b/api/golang/http_rest/server/engine_rest_api/engine_server.gen.go @@ -750,33 +750,34 @@ func (sh *strictHandler) GetEngineInfo(ctx echo.Context) error { // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", + "iCcuE2ssTUsvan866rf7/wMAAP//IQrWlZYgAAA=", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/api/openapi/specs/kurtosis_api.yaml b/api/openapi/specs/kurtosis_api.yaml index c5627cf706..150cc927bd 100644 --- a/api/openapi/specs/kurtosis_api.yaml +++ b/api/openapi/specs/kurtosis_api.yaml @@ -840,6 +840,10 @@ components: mode: $ref: "#/components/schemas/EnclaveMode" description: Enclave mode, defaults to TEST + should_apic_run_in_debug_mode: + $ref: "#/components/schemas/ApiContainerDebugMode" + # This is not an EnclaveMode because we will need to debug both current Modes (Test and Prod) + description: Whether the APIC's container should run with the debug server to receive a remote debug connection required: - enclave_name - api_container_version_tag @@ -869,6 +873,13 @@ components: - STOPPED - NON_EXISTENT + ApiContainerDebugMode: + type: boolean + default: false + enum: + - false + - true + EnclaveInfo: type: object properties: diff --git a/api/protobuf/engine/engine_service.proto b/api/protobuf/engine/engine_service.proto index 87e40bcdbb..0e8dcfb022 100644 --- a/api/protobuf/engine/engine_service.proto +++ b/api/protobuf/engine/engine_service.proto @@ -51,6 +51,10 @@ message CreateEnclaveArgs { optional string api_container_log_level = 3; optional EnclaveMode mode = 4; + + // Whether the APIC's container should run with the debug server to receive a remote debug connection + // This is not an EnclaveMode because we will need to debug both current Modes (Test and Prod) + optional bool should_apic_run_in_debug_mode = 5; } enum EnclaveMode { diff --git a/api/rust/src/engine_api.rs b/api/rust/src/engine_api.rs index c816267b66..c2d281cc69 100644 --- a/api/rust/src/engine_api.rs +++ b/api/rust/src/engine_api.rs @@ -28,6 +28,10 @@ pub struct CreateEnclaveArgs { pub api_container_log_level: ::core::option::Option<::prost::alloc::string::String>, #[prost(enumeration = "EnclaveMode", optional, tag = "4")] pub mode: ::core::option::Option, + /// Whether the APIC's container should run with the debug server to receive a remote debug connection + /// This is not an EnclaveMode because we will need to debug both current Modes (Test and Prod) + #[prost(bool, optional, tag = "5")] + pub should_apic_run_in_debug_mode: ::core::option::Option, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] diff --git a/api/typescript/src/engine/kurtosis_engine_rpc_api_bindings/connect/engine_service_pb.d.ts b/api/typescript/src/engine/kurtosis_engine_rpc_api_bindings/connect/engine_service_pb.d.ts index f0ab878b01..269a10fde9 100644 --- a/api/typescript/src/engine/kurtosis_engine_rpc_api_bindings/connect/engine_service_pb.d.ts +++ b/api/typescript/src/engine/kurtosis_engine_rpc_api_bindings/connect/engine_service_pb.d.ts @@ -177,6 +177,14 @@ export declare class CreateEnclaveArgs extends Message { */ mode?: EnclaveMode; + /** + * Whether the APIC's container should run with the debug server to receive a remote debug connection + * This is not an EnclaveMode because we will need to debug both current Modes (Test and Prod) + * + * @generated from field: optional bool should_apic_run_in_debug_mode = 5; + */ + shouldApicRunInDebugMode?: boolean; + constructor(data?: PartialMessage); static readonly runtime: typeof proto3; diff --git a/api/typescript/src/engine/kurtosis_engine_rpc_api_bindings/connect/engine_service_pb.js b/api/typescript/src/engine/kurtosis_engine_rpc_api_bindings/connect/engine_service_pb.js index 6a8a9cfd9c..24c994a6f4 100644 --- a/api/typescript/src/engine/kurtosis_engine_rpc_api_bindings/connect/engine_service_pb.js +++ b/api/typescript/src/engine/kurtosis_engine_rpc_api_bindings/connect/engine_service_pb.js @@ -92,6 +92,7 @@ export const CreateEnclaveArgs = proto3.makeMessageType( { no: 2, name: "api_container_version_tag", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, { no: 3, name: "api_container_log_level", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, { no: 4, name: "mode", kind: "enum", T: proto3.getEnumType(EnclaveMode), opt: true }, + { no: 5, name: "should_apic_run_in_debug_mode", kind: "scalar", T: 8 /* ScalarType.BOOL */, opt: true }, ], ); diff --git a/api/typescript/src/engine/kurtosis_engine_rpc_api_bindings/engine_service_pb.d.ts b/api/typescript/src/engine/kurtosis_engine_rpc_api_bindings/engine_service_pb.d.ts index ee7c174bda..06fc96768c 100644 --- a/api/typescript/src/engine/kurtosis_engine_rpc_api_bindings/engine_service_pb.d.ts +++ b/api/typescript/src/engine/kurtosis_engine_rpc_api_bindings/engine_service_pb.d.ts @@ -43,6 +43,11 @@ export class CreateEnclaveArgs extends jspb.Message { hasMode(): boolean; clearMode(): CreateEnclaveArgs; + getShouldApicRunInDebugMode(): boolean; + setShouldApicRunInDebugMode(value: boolean): CreateEnclaveArgs; + hasShouldApicRunInDebugMode(): boolean; + clearShouldApicRunInDebugMode(): CreateEnclaveArgs; + serializeBinary(): Uint8Array; toObject(includeInstance?: boolean): CreateEnclaveArgs.AsObject; static toObject(includeInstance: boolean, msg: CreateEnclaveArgs): CreateEnclaveArgs.AsObject; @@ -57,6 +62,7 @@ export namespace CreateEnclaveArgs { apiContainerVersionTag?: string, apiContainerLogLevel?: string, mode?: EnclaveMode, + shouldApicRunInDebugMode?: boolean, } export enum EnclaveNameCase { @@ -78,6 +84,11 @@ export namespace CreateEnclaveArgs { _MODE_NOT_SET = 0, MODE = 4, } + + export enum ShouldApicRunInDebugModeCase { + _SHOULD_APIC_RUN_IN_DEBUG_MODE_NOT_SET = 0, + SHOULD_APIC_RUN_IN_DEBUG_MODE = 5, + } } export class CreateEnclaveResponse extends jspb.Message { diff --git a/api/typescript/src/engine/kurtosis_engine_rpc_api_bindings/engine_service_pb.js b/api/typescript/src/engine/kurtosis_engine_rpc_api_bindings/engine_service_pb.js index 32f4a327a6..dbd7436b72 100644 --- a/api/typescript/src/engine/kurtosis_engine_rpc_api_bindings/engine_service_pb.js +++ b/api/typescript/src/engine/kurtosis_engine_rpc_api_bindings/engine_service_pb.js @@ -590,7 +590,8 @@ proto.engine_api.CreateEnclaveArgs.toObject = function(includeInstance, msg) { enclaveName: jspb.Message.getFieldWithDefault(msg, 1, ""), apiContainerVersionTag: jspb.Message.getFieldWithDefault(msg, 2, ""), apiContainerLogLevel: jspb.Message.getFieldWithDefault(msg, 3, ""), - mode: jspb.Message.getFieldWithDefault(msg, 4, 0) + mode: jspb.Message.getFieldWithDefault(msg, 4, 0), + shouldApicRunInDebugMode: jspb.Message.getBooleanFieldWithDefault(msg, 5, false) }; if (includeInstance) { @@ -643,6 +644,10 @@ proto.engine_api.CreateEnclaveArgs.deserializeBinaryFromReader = function(msg, r var value = /** @type {!proto.engine_api.EnclaveMode} */ (reader.readEnum()); msg.setMode(value); break; + case 5: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setShouldApicRunInDebugMode(value); + break; default: reader.skipField(); break; @@ -700,6 +705,13 @@ proto.engine_api.CreateEnclaveArgs.serializeBinaryToWriter = function(message, w f ); } + f = /** @type {boolean} */ (jspb.Message.getField(message, 5)); + if (f != null) { + writer.writeBool( + 5, + f + ); + } }; @@ -847,6 +859,42 @@ proto.engine_api.CreateEnclaveArgs.prototype.hasMode = function() { }; +/** + * optional bool should_apic_run_in_debug_mode = 5; + * @return {boolean} + */ +proto.engine_api.CreateEnclaveArgs.prototype.getShouldApicRunInDebugMode = function() { + return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 5, false)); +}; + + +/** + * @param {boolean} value + * @return {!proto.engine_api.CreateEnclaveArgs} returns this + */ +proto.engine_api.CreateEnclaveArgs.prototype.setShouldApicRunInDebugMode = function(value) { + return jspb.Message.setField(this, 5, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.engine_api.CreateEnclaveArgs} returns this + */ +proto.engine_api.CreateEnclaveArgs.prototype.clearShouldApicRunInDebugMode = function() { + return jspb.Message.setField(this, 5, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.engine_api.CreateEnclaveArgs.prototype.hasShouldApicRunInDebugMode = function() { + return jspb.Message.getField(this, 5) != null; +}; + + diff --git a/api/typescript/src/engine/lib/constructor_calls.ts b/api/typescript/src/engine/lib/constructor_calls.ts index ec61fd68dc..30f99a3ab7 100644 --- a/api/typescript/src/engine/lib/constructor_calls.ts +++ b/api/typescript/src/engine/lib/constructor_calls.ts @@ -18,11 +18,13 @@ import * as kurtosisLogLineOperator from "./kurtosis_context/log_line_operator"; export function newCreateEnclaveArgs( enclaveName: string, apiContainerImageVersionTag: string, - apiContainerLogLevel: string): CreateEnclaveArgs { + apiContainerLogLevel: string, + shouldApicRunInDebugMode: boolean): CreateEnclaveArgs { const result: CreateEnclaveArgs = new CreateEnclaveArgs(); result.setEnclaveName(enclaveName); result.setApiContainerVersionTag(apiContainerImageVersionTag); result.setApiContainerLogLevel(apiContainerLogLevel); + result.setShouldApicRunInDebugMode(shouldApicRunInDebugMode); return result; } diff --git a/api/typescript/src/engine/lib/kurtosis_context/kurtosis_context.ts b/api/typescript/src/engine/lib/kurtosis_context/kurtosis_context.ts index 88ee484564..1502dcd845 100644 --- a/api/typescript/src/engine/lib/kurtosis_context/kurtosis_context.ts +++ b/api/typescript/src/engine/lib/kurtosis_context/kurtosis_context.ts @@ -44,6 +44,9 @@ export const DEFAULT_GRPC_ENGINE_SERVER_PORT_NUM: number = 9710; // Blank tells the engine server to use the default const DEFAULT_API_CONTAINER_VERSION_TAG = ""; +const DEFAULT_SHOULD_APIC_RUN_IN_DEBUG_MODE = false +const RUN_APIC_IN_DEBUG_MODE = true + // Docs available at https://docs.kurtosis.com/sdk#kurtosiscontext export class KurtosisContext { private readonly client: GenericEngineClient @@ -88,32 +91,25 @@ export class KurtosisContext { // Docs available at https://docs.kurtosis.com/sdk#createenclaveenclaveid-enclaveid-boolean-issubnetworkingenabled---enclavecontextenclavecontext-enclavecontext public async createEnclave(enclaveName: string): Promise> { - const subnetworkDisableBecauseItIsDeprecated = false const enclaveArgs: CreateEnclaveArgs = newCreateEnclaveArgs( enclaveName, DEFAULT_API_CONTAINER_VERSION_TAG, API_CONTAINER_LOG_LEVEL, + DEFAULT_SHOULD_APIC_RUN_IN_DEBUG_MODE, ); - const getEnclaveResponseResult = await this.client.createEnclaveResponse(enclaveArgs) - if(getEnclaveResponseResult.isErr()){ - return err(getEnclaveResponseResult.error) - } - - const enclaveResponse: CreateEnclaveResponse = getEnclaveResponseResult.value; - const enclaveInfo: EnclaveInfo | undefined = enclaveResponse.getEnclaveInfo(); - if (enclaveInfo === undefined) { - return err(new Error("An error occurred creating enclave with name " + enclaveName + " enclaveInfo is undefined; " + - "this is a bug on this library" )) - } + return this.createEnclaveWithArgs(enclaveArgs) + } - const newEnclaveContextResult: Result = await this.newEnclaveContextFromEnclaveInfo(enclaveInfo); - if (newEnclaveContextResult.isErr()) { - return err(new Error(`An error occurred creating an enclave context from a newly-created enclave; this should never happen`)) - } + public async createEnclaveWithDebugEnabled(enclaveName: string): Promise> { + const enclaveArgs: CreateEnclaveArgs = newCreateEnclaveArgs( + enclaveName, + DEFAULT_API_CONTAINER_VERSION_TAG, + API_CONTAINER_LOG_LEVEL, + RUN_APIC_IN_DEBUG_MODE, + ); - const enclaveContext = newEnclaveContextResult.value - return ok(enclaveContext); + return this.createEnclaveWithArgs(enclaveArgs) } // Docs available at https://docs.kurtosis.com/sdk/#getenclavecontextstring-enclaveidentifier---enclavecontextenclavecontext-enclavecontext @@ -351,4 +347,27 @@ export class KurtosisContext { return ok(null) } + + async createEnclaveWithArgs(enclaveArgs: CreateEnclaveArgs): Promise> { + const getEnclaveResponseResult = await this.client.createEnclaveResponse(enclaveArgs) + if(getEnclaveResponseResult.isErr()){ + return err(getEnclaveResponseResult.error) + } + + const enclaveResponse: CreateEnclaveResponse = getEnclaveResponseResult.value; + const enclaveInfo: EnclaveInfo | undefined = enclaveResponse.getEnclaveInfo(); + if (enclaveInfo === undefined) { + return err(new Error("An error occurred creating enclave with name " + enclaveArgs.getEnclaveName() + " enclaveInfo is undefined; " + + "this is a bug on this library" )) + } + + const newEnclaveContextResult: Result = await this.newEnclaveContextFromEnclaveInfo(enclaveInfo); + if (newEnclaveContextResult.isErr()) { + return err(new Error(`An error occurred creating an enclave context from a newly-created enclave; this should never happen`)) + } + + const enclaveContext = newEnclaveContextResult.value + return ok(enclaveContext); + } + } diff --git a/api/typescript/src/engine/rest_api_bindings/types.d.ts b/api/typescript/src/engine/rest_api_bindings/types.d.ts index d51959c210..4764b775d6 100644 --- a/api/typescript/src/engine/rest_api_bindings/types.d.ts +++ b/api/typescript/src/engine/rest_api_bindings/types.d.ts @@ -1194,6 +1194,8 @@ export interface components { api_container_log_level?: string; /** @description Enclave mode, defaults to TEST */ mode?: components["schemas"]["EnclaveMode"]; + /** @description Whether the APIC's container should run with the debug server to receive a remote debug connection */ + should_apic_run_in_debug_mode?: components["schemas"]["ApiContainerDebugMode"]; }; /** @enum {string} */ EnclaveMode: "TEST" | "PRODUCTION"; @@ -1203,6 +1205,11 @@ export interface components { EnclaveTargetStatus: "STOP"; /** @enum {string} */ ApiContainerStatus: "RUNNING" | "STOPPED" | "NON_EXISTENT"; + /** + * @default false + * @enum {boolean} + */ + ApiContainerDebugMode: false | true; EnclaveInfo: { enclave_uuid: string; name: string; diff --git a/cli/cli/commands/enclave/add/add.go b/cli/cli/commands/enclave/add/add.go index 7e2e8293ff..e9cbb57c0a 100644 --- a/cli/cli/commands/enclave/add/add.go +++ b/cli/cli/commands/enclave/add/add.go @@ -14,6 +14,7 @@ import ( "github.com/kurtosis-tech/kurtosis/cli/cli/helpers/logrus_log_levels" "github.com/kurtosis-tech/kurtosis/cli/cli/helpers/output_printers" "github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface" + "github.com/kurtosis-tech/kurtosis/kurtosis_version" "github.com/kurtosis-tech/kurtosis/metrics-library/golang/lib/metrics_client" "github.com/kurtosis-tech/stacktrace" "github.com/sirupsen/logrus" @@ -93,6 +94,17 @@ func run( return stacktrace.Propagate(err, "An error occurred while getting the API Container Version using flag with key '%v'; this is a bug in Kurtosis", apiContainerVersionFlagKey) } + isDebugMode, err := flags.GetBool(defaults.DebugModeFlagKey) + if err != nil { + return stacktrace.Propagate(err, "Expected a value for the '%v' flag but failed to get it", defaults.DebugModeFlagKey) + } + + shouldApicRunInDebugMode := defaults.DefaultEnableDebugMode + if isDebugMode && apiContainerVersion == defaults.DefaultAPIContainerVersion { + apiContainerVersion = fmt.Sprintf("%s-%s", kurtosis_version.KurtosisVersion, defaults.DefaultKurtosisContainerDebugImageNameSuffix) + shouldApicRunInDebugMode = true + } + kurtosisLogLevelStr, err := flags.GetString(apiContainerLogLevelFlagKey) if err != nil { return stacktrace.Propagate(err, "An error occurred while getting the API Container log level using flag with key '%v'; this is a bug in Kurtosis", apiContainerLogLevelFlagKey) @@ -131,10 +143,11 @@ func run( } createEnclaveArgs := &kurtosis_engine_rpc_api_bindings.CreateEnclaveArgs{ - EnclaveName: &enclaveName, - ApiContainerVersionTag: &apiContainerVersion, - ApiContainerLogLevel: &kurtosisLogLevelStr, - Mode: &mode, + EnclaveName: &enclaveName, + ApiContainerVersionTag: &apiContainerVersion, + ApiContainerLogLevel: &kurtosisLogLevelStr, + Mode: &mode, + ShouldApicRunInDebugMode: &shouldApicRunInDebugMode, } createdEnclaveResponse, err := engineClient.CreateEnclave(ctx, createEnclaveArgs) if err != nil { diff --git a/cli/cli/commands/import/import.go b/cli/cli/commands/import/import.go index 42add2faff..13583d192f 100644 --- a/cli/cli/commands/import/import.go +++ b/cli/cli/commands/import/import.go @@ -11,7 +11,6 @@ import ( "github.com/kurtosis-tech/kurtosis/api/golang/engine/kurtosis_engine_rpc_api_bindings" enclave_consts "github.com/kurtosis-tech/kurtosis/api/golang/engine/lib/enclave" "github.com/kurtosis-tech/kurtosis/api/golang/engine/lib/kurtosis_context" - command_args_run "github.com/kurtosis-tech/kurtosis/cli/cli/command_args/run" "github.com/kurtosis-tech/kurtosis/cli/cli/command_framework/highlevel/engine_consuming_kurtosis_command" "github.com/kurtosis-tech/kurtosis/cli/cli/command_framework/highlevel/file_system_path_arg" @@ -155,6 +154,7 @@ func run( if err != nil { return stacktrace.Propagate(err, "Couldn't find enclave name flag '%v'", enclaveNameFlagKey) } + enclaveCtx, err := createEnclave(ctx, kurtosisCtx, enclaveName) if err != nil { return stacktrace.Propagate(err, "Couldn't create enclave") diff --git a/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/docker_kurtosis_backend_api_container_functions.go b/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/docker_kurtosis_backend_api_container_functions.go index c39caf00ce..bfbf53d0a2 100644 --- a/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/docker_kurtosis_backend_api_container_functions.go +++ b/container-engine-lib/lib/backend_impls/docker/docker_kurtosis_backend/docker_kurtosis_backend_api_container_functions.go @@ -31,6 +31,8 @@ const ( maxWaitForApiContainerAvailabilityRetries = 10 timeBetweenWaitForApiContainerAvailabilityRetries = 1 * time.Second + + apicDebugServerPort = 50103 // in ClI this is 50101 and in engine is 50102 ) // TODO: MIGRATE THIS FOLDER TO USE STRUCTURE OF USER_SERVICE_FUNCTIONS MODULE @@ -46,6 +48,7 @@ func (backend *DockerKurtosisBackend) CreateAPIContainer( enclaveDataVolumeDirpath string, ownIpAddressEnvVar string, customEnvVars map[string]string, + shouldStartInDebugMode bool, ) (*api_container.APIContainer, error) { logrus.Debugf("Creating the APIC for enclave '%v'", enclaveUuid) @@ -89,7 +92,7 @@ func (backend *DockerKurtosisBackend) CreateAPIContainer( } reverseProxyEnclaveNetworkIpAddress, found := reverseProxy.GetEnclaveNetworksIpAddress()[enclaveNetwork.GetId()] if !found { - return nil, stacktrace.NewError("An error occured while getting the reverse proxy enclave network IP address for enclave '%v', This is a bug in Kurtosis", enclaveUuid) + return nil, stacktrace.NewError("An error occurred while getting the reverse proxy enclave network IP address for enclave '%v', This is a bug in Kurtosis", enclaveUuid) } networkCidr := enclaveNetwork.GetIpAndMask() @@ -127,7 +130,7 @@ func (backend *DockerKurtosisBackend) CreateAPIContainer( err, "An error occurred creating the API container's private grpc port spec object using number '%v' and protocol '%v'", grpcPortNum, - consts.EngineTransportProtocol.String(), + apiContainerTransportProtocol, ) } @@ -149,10 +152,35 @@ func (backend *DockerKurtosisBackend) CreateAPIContainer( if err != nil { return nil, stacktrace.Propagate(err, "An error occurred transforming the private grpc port spec to a Docker port") } + usedPorts := map[nat.Port]docker_manager.PortPublishSpec{ privateGrpcDockerPort: docker_manager.NewAutomaticPublishingSpec(), } + if shouldStartInDebugMode { + debugServerPortSpec, err := port_spec.NewPortSpec( + uint16(apicDebugServerPort), + apiContainerTransportProtocol, + consts.HttpApplicationProtocol, + defaultWait, + ) + if err != nil { + return nil, stacktrace.Propagate( + err, + "An error occurred creating the API container's debug server port spec object using number '%v' and protocol '%v'", + apicDebugServerPort, + apiContainerTransportProtocol, + ) + } + + debugServerDockerPort, err := shared_helpers.TransformPortSpecToDockerPort(debugServerPortSpec) + if err != nil { + return nil, stacktrace.Propagate(err, "An error occurred transforming the debug server port spec to a Docker port") + } + + usedPorts[debugServerDockerPort] = docker_manager.NewManualPublishingSpec(uint16(apicDebugServerPort)) + } + bindMounts := map[string]string{ // Necessary so that the API container can interact with the Docker engine consts.DockerSocketFilepath: consts.DockerSocketFilepath, @@ -168,7 +196,7 @@ func (backend *DockerKurtosisBackend) CreateAPIContainer( } // TODO: configure the APIContainer to send the logs to the Fluentbit logs collector server - createAndStartArgs := docker_manager.NewCreateAndStartContainerArgsBuilder( + createAndStartArgsBuilder := docker_manager.NewCreateAndStartContainerArgsBuilder( image, apiContainerAttrs.GetName().GetString(), enclaveNetwork.GetId(), @@ -184,7 +212,23 @@ func (backend *DockerKurtosisBackend) CreateAPIContainer( ipAddr, ).WithLabels( labelStrs, - ).WithRestartPolicy(docker_manager.RestartOnFailure).Build() + ).WithRestartPolicy(docker_manager.RestartOnFailure) + + if shouldStartInDebugMode { + // Adding systrace capabilities when starting the debug server in the engine's container + capabilities := map[docker_manager.ContainerCapability]bool{ + docker_manager.SysPtrace: true, + } + createAndStartArgsBuilder.WithAddedCapabilities(capabilities) + + // Setting security for debugging the engine's container + securityOpts := map[docker_manager.ContainerSecurityOpt]bool{ + docker_manager.AppArmorUnconfined: true, + } + createAndStartArgsBuilder.WithSecurityOpts(securityOpts) + } + + createAndStartArgs := createAndStartArgsBuilder.Build() if _, err = backend.dockerManager.FetchImageIfMissing(ctx, image, emptyRegistrySpecAsPublicImage); err != nil { logrus.Warnf("Failed to pull the latest version of API container image '%v'; you may be running an out-of-date version. Error:\n%v", image, err) diff --git a/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_kurtosis_backend/kubernetes_kurtosis_backend_api_container_functions.go b/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_kurtosis_backend/kubernetes_kurtosis_backend_api_container_functions.go index 814e50ebf8..2d6fafa414 100644 --- a/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_kurtosis_backend/kubernetes_kurtosis_backend_api_container_functions.go +++ b/container-engine-lib/lib/backend_impls/kubernetes/kubernetes_kurtosis_backend/kubernetes_kurtosis_backend_api_container_functions.go @@ -74,6 +74,7 @@ func (backend *KubernetesKurtosisBackend) CreateAPIContainer( enclaveDataVolumeDirpath string, ownIpAddressEnvVar string, customEnvVars map[string]string, + shouldStartInDebugMode bool, ) ( *api_container.APIContainer, error, diff --git a/container-engine-lib/lib/backend_impls/metrics_reporting/metrics_reporting_kurtosis_backend.go b/container-engine-lib/lib/backend_impls/metrics_reporting/metrics_reporting_kurtosis_backend.go index 87d98da01a..dcdbbf3b74 100644 --- a/container-engine-lib/lib/backend_impls/metrics_reporting/metrics_reporting_kurtosis_backend.go +++ b/container-engine-lib/lib/backend_impls/metrics_reporting/metrics_reporting_kurtosis_backend.go @@ -200,6 +200,7 @@ func (backend *MetricsReportingKurtosisBackend) CreateAPIContainer( enclaveDataVolumeDirpath string, ownIpEnvVar string, customEnvVars map[string]string, + shouldStartInDebugMode bool, ) (*api_container.APIContainer, error) { if _, found := customEnvVars[ownIpEnvVar]; found { return nil, stacktrace.NewError("Requested own IP environment variable '%v' conflicts with custom environment variable", ownIpEnvVar) @@ -213,6 +214,7 @@ func (backend *MetricsReportingKurtosisBackend) CreateAPIContainer( enclaveDataVolumeDirpath, ownIpEnvVar, customEnvVars, + shouldStartInDebugMode, ) if err != nil { // WARNING: remember not to print 'customEnvVars' because it could end up creating a secret info leak diff --git a/container-engine-lib/lib/backend_interface/kurtosis_backend.go b/container-engine-lib/lib/backend_interface/kurtosis_backend.go index d7b655d70b..0e23bf4f8e 100644 --- a/container-engine-lib/lib/backend_interface/kurtosis_backend.go +++ b/container-engine-lib/lib/backend_interface/kurtosis_backend.go @@ -140,6 +140,7 @@ type KurtosisBackend interface { // Must not conflict with the custom environment variables ownIpAddressEnvVar string, customEnvVars map[string]string, + shouldStartInDebugMode bool, ) ( *api_container.APIContainer, error, diff --git a/container-engine-lib/lib/backend_interface/mock_kurtosis_backend.go b/container-engine-lib/lib/backend_interface/mock_kurtosis_backend.go index dd68bb93fd..554300cdae 100644 --- a/container-engine-lib/lib/backend_interface/mock_kurtosis_backend.go +++ b/container-engine-lib/lib/backend_interface/mock_kurtosis_backend.go @@ -156,9 +156,13 @@ func (_c *MockKurtosisBackend_CopyFilesFromUserService_Call) RunAndReturn(run fu return _c } -// CreateAPIContainer provides a mock function with given fields: ctx, image, enclaveUuid, grpcPortNum, enclaveDataVolumeDirpath, ownIpAddressEnvVar, customEnvVars -func (_m *MockKurtosisBackend) CreateAPIContainer(ctx context.Context, image string, enclaveUuid enclave.EnclaveUUID, grpcPortNum uint16, enclaveDataVolumeDirpath string, ownIpAddressEnvVar string, customEnvVars map[string]string) (*api_container.APIContainer, error) { - ret := _m.Called(ctx, image, enclaveUuid, grpcPortNum, enclaveDataVolumeDirpath, ownIpAddressEnvVar, customEnvVars) +// CreateAPIContainer provides a mock function with given fields: ctx, image, enclaveUuid, grpcPortNum, enclaveDataVolumeDirpath, ownIpAddressEnvVar, customEnvVars, shouldStartInDebugMode +func (_m *MockKurtosisBackend) CreateAPIContainer(ctx context.Context, image string, enclaveUuid enclave.EnclaveUUID, grpcPortNum uint16, enclaveDataVolumeDirpath string, ownIpAddressEnvVar string, customEnvVars map[string]string, shouldStartInDebugMode bool) (*api_container.APIContainer, error) { + ret := _m.Called(ctx, image, enclaveUuid, grpcPortNum, enclaveDataVolumeDirpath, ownIpAddressEnvVar, customEnvVars, shouldStartInDebugMode) + + if len(ret) == 0 { + panic("no return value specified for CreateAPIContainer") + } if len(ret) == 0 { panic("no return value specified for CreateAPIContainer") @@ -166,19 +170,19 @@ func (_m *MockKurtosisBackend) CreateAPIContainer(ctx context.Context, image str var r0 *api_container.APIContainer var r1 error - if rf, ok := ret.Get(0).(func(context.Context, string, enclave.EnclaveUUID, uint16, string, string, map[string]string) (*api_container.APIContainer, error)); ok { - return rf(ctx, image, enclaveUuid, grpcPortNum, enclaveDataVolumeDirpath, ownIpAddressEnvVar, customEnvVars) + if rf, ok := ret.Get(0).(func(context.Context, string, enclave.EnclaveUUID, uint16, string, string, map[string]string, bool) (*api_container.APIContainer, error)); ok { + return rf(ctx, image, enclaveUuid, grpcPortNum, enclaveDataVolumeDirpath, ownIpAddressEnvVar, customEnvVars, shouldStartInDebugMode) } - if rf, ok := ret.Get(0).(func(context.Context, string, enclave.EnclaveUUID, uint16, string, string, map[string]string) *api_container.APIContainer); ok { - r0 = rf(ctx, image, enclaveUuid, grpcPortNum, enclaveDataVolumeDirpath, ownIpAddressEnvVar, customEnvVars) + if rf, ok := ret.Get(0).(func(context.Context, string, enclave.EnclaveUUID, uint16, string, string, map[string]string, bool) *api_container.APIContainer); ok { + r0 = rf(ctx, image, enclaveUuid, grpcPortNum, enclaveDataVolumeDirpath, ownIpAddressEnvVar, customEnvVars, shouldStartInDebugMode) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*api_container.APIContainer) } } - if rf, ok := ret.Get(1).(func(context.Context, string, enclave.EnclaveUUID, uint16, string, string, map[string]string) error); ok { - r1 = rf(ctx, image, enclaveUuid, grpcPortNum, enclaveDataVolumeDirpath, ownIpAddressEnvVar, customEnvVars) + if rf, ok := ret.Get(1).(func(context.Context, string, enclave.EnclaveUUID, uint16, string, string, map[string]string, bool) error); ok { + r1 = rf(ctx, image, enclaveUuid, grpcPortNum, enclaveDataVolumeDirpath, ownIpAddressEnvVar, customEnvVars, shouldStartInDebugMode) } else { r1 = ret.Error(1) } @@ -199,13 +203,14 @@ type MockKurtosisBackend_CreateAPIContainer_Call struct { // - enclaveDataVolumeDirpath string // - ownIpAddressEnvVar string // - customEnvVars map[string]string -func (_e *MockKurtosisBackend_Expecter) CreateAPIContainer(ctx interface{}, image interface{}, enclaveUuid interface{}, grpcPortNum interface{}, enclaveDataVolumeDirpath interface{}, ownIpAddressEnvVar interface{}, customEnvVars interface{}) *MockKurtosisBackend_CreateAPIContainer_Call { - return &MockKurtosisBackend_CreateAPIContainer_Call{Call: _e.mock.On("CreateAPIContainer", ctx, image, enclaveUuid, grpcPortNum, enclaveDataVolumeDirpath, ownIpAddressEnvVar, customEnvVars)} +// - shouldStartInDebugMode bool +func (_e *MockKurtosisBackend_Expecter) CreateAPIContainer(ctx interface{}, image interface{}, enclaveUuid interface{}, grpcPortNum interface{}, enclaveDataVolumeDirpath interface{}, ownIpAddressEnvVar interface{}, customEnvVars interface{}, shouldStartInDebugMode interface{}) *MockKurtosisBackend_CreateAPIContainer_Call { + return &MockKurtosisBackend_CreateAPIContainer_Call{Call: _e.mock.On("CreateAPIContainer", ctx, image, enclaveUuid, grpcPortNum, enclaveDataVolumeDirpath, ownIpAddressEnvVar, customEnvVars, shouldStartInDebugMode)} } -func (_c *MockKurtosisBackend_CreateAPIContainer_Call) Run(run func(ctx context.Context, image string, enclaveUuid enclave.EnclaveUUID, grpcPortNum uint16, enclaveDataVolumeDirpath string, ownIpAddressEnvVar string, customEnvVars map[string]string)) *MockKurtosisBackend_CreateAPIContainer_Call { +func (_c *MockKurtosisBackend_CreateAPIContainer_Call) Run(run func(ctx context.Context, image string, enclaveUuid enclave.EnclaveUUID, grpcPortNum uint16, enclaveDataVolumeDirpath string, ownIpAddressEnvVar string, customEnvVars map[string]string, shouldStartInDebugMode bool)) *MockKurtosisBackend_CreateAPIContainer_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(enclave.EnclaveUUID), args[3].(uint16), args[4].(string), args[5].(string), args[6].(map[string]string)) + run(args[0].(context.Context), args[1].(string), args[2].(enclave.EnclaveUUID), args[3].(uint16), args[4].(string), args[5].(string), args[6].(map[string]string), args[7].(bool)) }) return _c } @@ -215,7 +220,7 @@ func (_c *MockKurtosisBackend_CreateAPIContainer_Call) Return(_a0 *api_container return _c } -func (_c *MockKurtosisBackend_CreateAPIContainer_Call) RunAndReturn(run func(context.Context, string, enclave.EnclaveUUID, uint16, string, string, map[string]string) (*api_container.APIContainer, error)) *MockKurtosisBackend_CreateAPIContainer_Call { +func (_c *MockKurtosisBackend_CreateAPIContainer_Call) RunAndReturn(run func(context.Context, string, enclave.EnclaveUUID, uint16, string, string, map[string]string, bool) (*api_container.APIContainer, error)) *MockKurtosisBackend_CreateAPIContainer_Call { _c.Call.Return(run) return _c } diff --git a/core/launcher/api_container_launcher/api_container_launcher.go b/core/launcher/api_container_launcher/api_container_launcher.go index f95583467a..9f49cd3943 100644 --- a/core/launcher/api_container_launcher/api_container_launcher.go +++ b/core/launcher/api_container_launcher/api_container_launcher.go @@ -45,6 +45,7 @@ func (launcher ApiContainerLauncher) LaunchWithDefaultVersion( isCI bool, cloudUserID metrics_client.CloudUserID, cloudInstanceID metrics_client.CloudInstanceID, + shouldStartInDebugMode bool, ) ( resultApiContainer *api_container.APIContainer, resultErr error, @@ -63,6 +64,7 @@ func (launcher ApiContainerLauncher) LaunchWithDefaultVersion( isCI, cloudUserID, cloudInstanceID, + shouldStartInDebugMode, ) if err != nil { return nil, stacktrace.Propagate(err, "An error occurred launching the API container with default version tag '%v'", kurtosis_version.KurtosisVersion) @@ -84,6 +86,7 @@ func (launcher ApiContainerLauncher) LaunchWithCustomVersion( isCI bool, cloudUserID metrics_client.CloudUserID, cloudInstanceID metrics_client.CloudInstanceID, + shouldStartInDebugMode bool, ) ( resultApiContainer *api_container.APIContainer, resultErr error, @@ -129,6 +132,7 @@ func (launcher ApiContainerLauncher) LaunchWithCustomVersion( enclaveDataVolumeDirpath, ownIpAddressEnvvar, envVars, + shouldStartInDebugMode, ) if err != nil { return nil, stacktrace.Propagate(err, "An error occurred launching the API container") diff --git a/core/scripts/build.sh b/core/scripts/build.sh index 02282fdd51..8f9bbe2991 100755 --- a/core/scripts/build.sh +++ b/core/scripts/build.sh @@ -10,19 +10,41 @@ root_dirpath="$(dirname "${script_dirpath}")" # ================================================================================================== # Constants # ================================================================================================== +DEFAULT_DEBUG_IMAGE=false +SET_ARCH_AUTOMATICALLY="" +DEFAULT_SKIP_DOCKER_IMAGE_BUILDING=false + BUILD_SCRIPT_RELATIVE_FILEPATHS=( "launcher/scripts/build.sh" "server/scripts/build.sh" "files_artifacts_expander/scripts/build.sh" ) +# ================================================================================================== +# Arg Parsing & Validation +# ================================================================================================== +show_helptext_and_exit() { + echo "Usage: $(basename "${0}") debug_image..." + echo "" + echo " debug_image Whether images should contains the debug server and run in debug mode, this will use the Dockerfile.debug image to build the container (configured for the APIC server so far)" + echo "" + exit 1 # Exit with an error so that if this is accidentally called by CI, the script will fail +} + +# Raw parsing of the arguments +debug_image="${1:-"${DEFAULT_DEBUG_IMAGE}"}" +if [ "${debug_image}" != "true" ] && [ "${debug_image}" != "false" ]; then + echo "Error: Invalid debug_image arg: '${debug_image}'" >&2 + show_helptext_and_exit +fi + # ================================================================================================== # Main Logic # ================================================================================================== for build_script_rel_filepath in "${BUILD_SCRIPT_RELATIVE_FILEPATHS[@]}"; do build_script_abs_filepath="${root_dirpath}/${build_script_rel_filepath}" - if ! bash "${build_script_abs_filepath}"; then + if ! bash "${build_script_abs_filepath}" "${DEFAULT_SKIP_DOCKER_IMAGE_BUILDING}" "${SET_ARCH_AUTOMATICALLY}" "${debug_image}"; then echo "Error: Build script '${build_script_abs_filepath}' failed" >&2 exit 1 fi diff --git a/core/server/Dockerfile.debug b/core/server/Dockerfile.debug new file mode 100644 index 0000000000..a8b268dc55 --- /dev/null +++ b/core/server/Dockerfile.debug @@ -0,0 +1,18 @@ +FROM alpine:3.19 + +# We need protobut-dev to run protobuf compiler against startosis .proto files +RUN apk update && apk add --no-cache bash protobuf-dev + +# Make sure that you changed the port inside the APIC's code before changing it here +EXPOSE 50103 + +ARG TARGETARCH + +WORKDIR /run + +COPY ./build/api-container.$TARGETARCH ./api-container + +COPY ./build/dlv.$TARGETARCH /dlv + +# Make sure that you changed the port inside the engine's code before changing it here +CMD ["/dlv", "--listen=:50103", "--headless=true", "--api-version=2", "--accept-multiclient", "exec", "--continue", "./api-container"] diff --git a/core/server/scripts/_constants.env b/core/server/scripts/_constants.env index e8e6258638..d151d2fe13 100644 --- a/core/server/scripts/_constants.env +++ b/core/server/scripts/_constants.env @@ -8,3 +8,11 @@ # constant in the 'launcher' submodule!! IMAGE_ORG_AND_REPO="kurtosistech/core" # ^^^^^^^^^^^^^^^^ WARNING ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +BUILD_DIRNAME="build" +DEFAULT_ARCHITECTURE_TO_BUILD="unknown" +DEFAULT_SKIP_DOCKER_IMAGE_BUILDING=false +DOCKER_IMAGE_FILENAME="Dockerfile" +DOCKER_DEBUG_IMAGE_FILENAME="${DOCKER_IMAGE_FILENAME}.debug" +DOCKER_DEBUG_IMAGE_NAME_SUFFIX="debug" +DEFAULT_DEBUG_IMAGE=false diff --git a/core/server/scripts/build.sh b/core/server/scripts/build.sh index 0930255de5..81b8f70a6f 100755 --- a/core/server/scripts/build.sh +++ b/core/server/scripts/build.sh @@ -11,12 +11,6 @@ uname_arch=$(uname -m) # ================================================================================================== source "${script_dirpath}/_constants.env" -BUILD_DIRNAME="build" - -DEFAULT_SKIP_DOCKER_IMAGE_BUILDING=false - -DEFAULT_ARCHITECTURE_TO_BUILD="unknown" - if [ "$uname_arch" == "x86_64" ] || [ "$uname_arch" == "amd64" ]; then DEFAULT_ARCHITECTURE_TO_BUILD="amd64" elif [ "$uname_arch" == "aarch64" ] || [ "$uname_arch" == "arm64" ]; then @@ -28,9 +22,23 @@ MAIN_GO_FILEPATH="${server_root_dirpath}/${MAIN_DIRNAME}/main.go" MAIN_BINARY_OUTPUT_FILENAME="api-container" MAIN_BINARY_OUTPUT_FILEPATH="${server_root_dirpath}/${BUILD_DIRNAME}/${MAIN_BINARY_OUTPUT_FILENAME}" -# ============================================================================= -# Main Code -# ============================================================================= +DELVE_BINARY_FILENAME="dlv" +DELVE_BINARY_OUTPUT_FILEPATH="${server_root_dirpath}/${BUILD_DIRNAME}/${DELVE_BINARY_FILENAME}" + +# ================================================================================================== +# Arg Parsing & Validation +# ================================================================================================== +show_helptext_and_exit() { + echo "Usage: $(basename "${0}") skip_docker_image_building, architecture_to_build, debug_image..." + echo "" + echo " skip_docker_image_building Whether build the Docker image" + echo " architecture_to_build The desired architecture for the project's binaries" + echo " debug_image Whether images should contains the debug server and run in debug mode, this will use the Dockerfile.debug image to build the container" + echo "" + exit 1 # Exit with an error so that if this is accidentally called by CI, the script will fail +} + + skip_docker_image_building="${1:-"${DEFAULT_SKIP_DOCKER_IMAGE_BUILDING}"}" if [ "${skip_docker_image_building}" != "true" ] && [ "${skip_docker_image_building}" != "false" ]; then echo "Error: Invalid skip-docker-image-building arg '${skip_docker_image_building}'" >&2 @@ -41,6 +49,15 @@ if [ "${architecture_to_build}" != "amd64" ] && [ "${architecture_to_build}" != echo "Error: Invalid architecture-to-build arg '${architecture_to_build}'" >&2 fi +debug_image="${3:-"${DEFAULT_DEBUG_IMAGE}"}" +if [ "${debug_image}" != "true" ] && [ "${debug_image}" != "false" ]; then + echo "Error: Invalid debug_image arg: '${debug_image}'" >&2 + show_helptext_and_exit +fi + +# ============================================================================= +# Main Code +# ============================================================================= # Checks if dockerignore file is in the root path if ! [ -f "${server_root_dirpath}"/.dockerignore ]; then echo "Error: No .dockerignore file found in server root '${server_root_dirpath}'; this is required so Docker caching is enabled and the image builds remain quick" >&2 @@ -61,12 +78,46 @@ echo "Tests succeeded" # Build binary for packaging inside an Alpine Linux image echo "Building server main.go '${MAIN_GO_FILEPATH}'..." -if ! CGO_ENABLED=0 GOOS=linux GOARCH=${architecture_to_build} go build -o "${MAIN_BINARY_OUTPUT_FILEPATH}.${architecture_to_build}" "${MAIN_GO_FILEPATH}"; then +gc_flags="" +if "${debug_image}"; then + gc_flags="all=-N -l" +fi +if ! CGO_ENABLED=0 GOOS=linux GOARCH=${architecture_to_build} go build -gcflags="${gc_flags}" -o "${MAIN_BINARY_OUTPUT_FILEPATH}.${architecture_to_build}" "${MAIN_GO_FILEPATH}"; then echo "Error: An error occurred building the server code" >&2 exit 1 fi echo "Successfully built server code" +# TODO move this to its own file because it's duplicated in the engine's build script +# Install and copy delve (the server debugger: https://github.com/go-delve/delve) to include it into the build folder so it can be picked up from the Docker image file +if "${debug_image}"; then + # Checks if the binary already exist + delve_exist="false" + dlv_go_folder_bin_filepath=~/go/bin/linux_"${architecture_to_build}"/"${DELVE_BINARY_FILENAME}" + dlv_bin_in_project_filepath="${DELVE_BINARY_OUTPUT_FILEPATH}.${architecture_to_build}" + # Check if it is in the build folder and skip if it is there + if ! [ -f "$dlv_bin_in_project_filepath" ]; then + # Check if it already exist in the goland folder + if ! [ -f "$dlv_go_folder_bin_filepath" ]; then + echo "Installing delve..." + if ! GOOS=linux GOARCH=${architecture_to_build} go install "${DELVE_SERVER_REPOSITORY_AND_VERSION}"; then + echo "Error: An error occurred installing the delve binary" >&2 + exit 1 + fi + echo "...delve successfully installed." + fi + # Now checks if the binary has been created + if ! [ -f "$dlv_go_folder_bin_filepath" ]; then + echo "Error: expected to have dlv binary in ${dlv_go_folder_bin_filepath} but it is not there." + exit 1 + fi + if ! cp "$dlv_go_folder_bin_filepath" "$dlv_bin_in_project_filepath" ; then + echo "Error: something failed while copying the delve binary from the GO bin folder to the project's build folder" + exit 1 + fi + fi +fi + # Generate Docker image tag if ! cd "${git_repo_dirpath}"; then echo "Error: Couldn't cd to the git root dirpath '${git_repo_dirpath}'" >&2 @@ -83,8 +134,19 @@ if "${skip_docker_image_building}"; then exit 0 fi -dockerfile_filepath="${server_root_dirpath}/Dockerfile" +dockerfile_filepath="${server_root_dirpath}/${DOCKER_IMAGE_FILENAME}" + +# Using the Docker debug image if it was requested +if "${debug_image}"; then + dockerfile_filepath="${server_root_dirpath}/${DOCKER_DEBUG_IMAGE_FILENAME}" +fi + image_name="${IMAGE_ORG_AND_REPO}:${docker_tag}" +# specifying that this is a image for debugging +if "${debug_image}"; then + image_name="${image_name}-${DOCKER_DEBUG_IMAGE_NAME_SUFFIX}" +fi + load_not_push_image=false docker_build_script_cmd="${git_repo_dirpath}/scripts/docker-image-builder.sh ${load_not_push_image} ${dockerfile_filepath} ${image_name}" if ! eval "${docker_build_script_cmd}"; then diff --git a/engine/scripts/build.sh b/engine/scripts/build.sh index b1c43e013b..136daecaee 100755 --- a/engine/scripts/build.sh +++ b/engine/scripts/build.sh @@ -25,7 +25,7 @@ BUILD_SCRIPT_RELATIVE_FILEPATHS=( show_helptext_and_exit() { echo "Usage: $(basename "${0}") debug_image..." echo "" - echo " debug_image Whether images should contains the debug server and run in debug mode, this will use the Dockerfile.debug image to build the container (only configured for the engine server so far)" + echo " debug_image Whether images should contains the debug server and run in debug mode, this will use the Dockerfile.debug image to build the container (configured for the engine server so far)" echo "" exit 1 # Exit with an error so that if this is accidentally called by CI, the script will fail } diff --git a/engine/server/engine/enclave_manager/enclave_creator.go b/engine/server/engine/enclave_manager/enclave_creator.go index c8708a1f8f..523c898da9 100644 --- a/engine/server/engine/enclave_manager/enclave_creator.go +++ b/engine/server/engine/enclave_manager/enclave_creator.go @@ -51,6 +51,7 @@ func (creator *EnclaveCreator) CreateEnclave( cloudUserID metrics_client.CloudUserID, cloudInstanceID metrics_client.CloudInstanceID, kurtosisBackendType args.KurtosisBackendType, + shouldAPICRunInDebugMode bool, ) (*types.EnclaveInfo, error) { uuid, err := uuid_generator.GenerateUUIDString() @@ -112,6 +113,7 @@ func (creator *EnclaveCreator) CreateEnclave( isCI, cloudUserID, cloudInstanceID, + shouldAPICRunInDebugMode, ) if err != nil { return nil, stacktrace.Propagate(err, "An error occurred launching the API container") @@ -198,6 +200,7 @@ func (creator *EnclaveCreator) launchApiContainer( isCI bool, cloudUserID metrics_client.CloudUserID, cloudInstanceID metrics_client.CloudInstanceID, + shouldStartInDebugMode bool, ) ( resultApiContainer *api_container.APIContainer, resultErr error, @@ -220,6 +223,7 @@ func (creator *EnclaveCreator) launchApiContainer( isCI, cloudUserID, cloudInstanceID, + shouldStartInDebugMode, ) if err != nil { return nil, stacktrace.Propagate(err, "Expected to be able to launch api container for enclave '%v' with custom version '%v', but an error occurred", enclaveUuid, apiContainerImageVersionTag) @@ -239,6 +243,7 @@ func (creator *EnclaveCreator) launchApiContainer( isCI, cloudUserID, cloudInstanceID, + shouldStartInDebugMode, ) if err != nil { return nil, stacktrace.Propagate(err, "Expected to be able to launch api container for enclave '%v' with the default version, but an error occurred", enclaveUuid) diff --git a/engine/server/engine/enclave_manager/enclave_manager.go b/engine/server/engine/enclave_manager/enclave_manager.go index 91ef2c8058..d966dd47bd 100644 --- a/engine/server/engine/enclave_manager/enclave_manager.go +++ b/engine/server/engine/enclave_manager/enclave_manager.go @@ -137,6 +137,7 @@ func (manager *EnclaveManager) CreateEnclave( //If blank, will use a random one enclaveName string, isProduction bool, + shouldAPICRunInDebugMode bool, ) (*types.EnclaveInfo, error) { manager.mutex.Lock() defer manager.mutex.Unlock() @@ -173,6 +174,7 @@ func (manager *EnclaveManager) CreateEnclave( engineVersion, apiContainerImageVersionTag, apiContainerLogLevel, + shouldAPICRunInDebugMode, ) if err != nil { logrus.Errorf("An error occurred when trying to get an enclave from the enclave pool. Err:\n%v", err) @@ -193,6 +195,7 @@ func (manager *EnclaveManager) CreateEnclave( manager.cloudUserID, manager.cloudInstanceID, manager.kurtosisBackendType, + shouldAPICRunInDebugMode, ) if err != nil { return nil, stacktrace.Propagate( diff --git a/engine/server/engine/enclave_manager/enclave_pool.go b/engine/server/engine/enclave_manager/enclave_pool.go index bf97ea2e04..459e7a36e4 100644 --- a/engine/server/engine/enclave_manager/enclave_pool.go +++ b/engine/server/engine/enclave_manager/enclave_pool.go @@ -22,6 +22,8 @@ const ( fill = true createTestEnclave = false + + defaultApicDebugModeForEnclavesInThePool = false ) type EnclavePool struct { @@ -122,6 +124,7 @@ func (pool *EnclavePool) GetEnclave( engineVersion string, apiContainerVersion string, apiContainerLogLevel logrus.Level, + shouldAPICRunInDebugMode bool, ) (*types.EnclaveInfo, error) { logrus.Debugf( @@ -139,6 +142,7 @@ func (pool *EnclavePool) GetEnclave( engineVersion, apiContainerVersion, apiContainerLogLevel, + shouldAPICRunInDebugMode, ) { logrus.Debugf("The requested enclave params are different from the enclave in the pool params") return nil, nil @@ -291,6 +295,7 @@ func (pool *EnclavePool) createNewIdleEnclave(ctx context.Context) (*types.Encla pool.cloudUserID, pool.cloudInstanceID, args.KurtosisBackendType_Kubernetes, // enclave pool only available for k8s + defaultApicDebugModeForEnclavesInThePool, ) if err != nil { return nil, stacktrace.Propagate( @@ -348,6 +353,7 @@ func areRequestedEnclaveParamsEqualToEnclaveInThePoolParams( engineVersion string, apiContainerVersion string, apiContainerLogLevel logrus.Level, + shouldAPICRunInDebugMode bool, ) bool { // if the api container version is empty string means that will be executed with the default version @@ -357,7 +363,7 @@ func areRequestedEnclaveParamsEqualToEnclaveInThePoolParams( } if engineVersion == apiContainerVersion && - apiContainerLogLevel == defaultApiContainerLogLevel { + apiContainerLogLevel == defaultApiContainerLogLevel && !shouldAPICRunInDebugMode { return true } diff --git a/engine/server/engine/server/engine_connect_server_service.go b/engine/server/engine/server/engine_connect_server_service.go index 29a48b8749..6dc9804e6b 100644 --- a/engine/server/engine/server/engine_connect_server_service.go +++ b/engine/server/engine/server/engine_connect_server_service.go @@ -187,6 +187,7 @@ func (service *EngineConnectServerService) CreateEnclave(ctx context.Context, co apiContainerLogLevel, args.GetEnclaveName(), isProduction, + args.GetShouldApicRunInDebugMode(), ) if err != nil { return nil, stacktrace.Propagate(err, "An error occurred creating new enclave with name '%v'", args.GetEnclaveName()) diff --git a/engine/server/engine/server/engine_rest_api_handler.go b/engine/server/engine/server/engine_rest_api_handler.go index 7af6f7a973..e7f9665024 100644 --- a/engine/server/engine/server/engine_rest_api_handler.go +++ b/engine/server/engine/server/engine_rest_api_handler.go @@ -74,6 +74,7 @@ func (engine EngineRuntime) PostEnclaves(ctx context.Context, request api.PostEn enclaveMode := utils.DerefWith(request.Body.Mode, api_type.TEST) enclaveName := request.Body.EnclaveName apicVersionTag := request.Body.ApiContainerVersionTag + shouldApicRunInDebugMode := utils.DerefWith(request.Body.ShouldApicRunInDebugMode, api_type.False) if err := engine.MetricsClient.TrackCreateEnclave(enclaveName, subnetworkDisableBecauseItIsDeprecated); err != nil { logrus.Warn("An error occurred while logging the create enclave event") @@ -106,6 +107,7 @@ func (engine EngineRuntime) PostEnclaves(ctx context.Context, request api.PostEn apiContainerLogLevel, enclaveName, isProduction, + bool(shouldApicRunInDebugMode), ) if err != nil { response := internalErrorResponseInfof(err, "An error occurred creating new enclave with name '%v'", request.Body.EnclaveName) diff --git a/internal_testsuites/typescript/yarn.lock b/internal_testsuites/typescript/yarn.lock index a77aeec02a..b9faf1d50b 100644 --- a/internal_testsuites/typescript/yarn.lock +++ b/internal_testsuites/typescript/yarn.lock @@ -10,68 +10,58 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.13": - version "7.22.13" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" - integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" + integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== dependencies: - "@babel/highlight" "^7.22.13" + "@babel/highlight" "^7.23.4" chalk "^2.4.2" -"@babel/compat-data@^7.22.9": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.20.tgz#8df6e96661209623f1975d66c35ffca66f3306d0" - integrity sha512-BQYjKbpXjoXwFW5jGqiizJQQT/aC7pFm9Ok1OWssonuguICi264lbgMzRp2ZMmRSlfkX6DsWDDcsrctK8Rwfiw== +"@babel/compat-data@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.5.tgz#ffb878728bb6bdcb6f4510aa51b1be9afb8cfd98" + integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== "@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.7.2", "@babel/core@^7.8.0": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.20.tgz#e3d0eed84c049e2a2ae0a64d27b6a37edec385b7" - integrity sha512-Y6jd1ahLubuYweD/zJH+vvOY141v4f9igNQAQ+MBgq9JlHS2iTsZKn1aMsb3vGccZsXI16VzTBw52Xx0DWmtnA== + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.9.tgz#b028820718000f267870822fec434820e9b1e4d1" + integrity sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw== dependencies: "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.22.13" - "@babel/generator" "^7.22.15" - "@babel/helper-compilation-targets" "^7.22.15" - "@babel/helper-module-transforms" "^7.22.20" - "@babel/helpers" "^7.22.15" - "@babel/parser" "^7.22.16" - "@babel/template" "^7.22.15" - "@babel/traverse" "^7.22.20" - "@babel/types" "^7.22.19" - convert-source-map "^1.7.0" + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.6" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helpers" "^7.23.9" + "@babel/parser" "^7.23.9" + "@babel/template" "^7.23.9" + "@babel/traverse" "^7.23.9" + "@babel/types" "^7.23.9" + convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.3" semver "^6.3.1" -"@babel/generator@^7.22.15", "@babel/generator@^7.7.2": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.15.tgz#1564189c7ec94cb8f77b5e8a90c4d200d21b2339" - integrity sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA== - dependencies: - "@babel/types" "^7.22.15" - "@jridgewell/gen-mapping" "^0.3.2" - "@jridgewell/trace-mapping" "^0.3.17" - jsesc "^2.5.1" - -"@babel/generator@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.0.tgz#df5c386e2218be505b34837acbcb874d7a983420" - integrity sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g== +"@babel/generator@^7.23.6", "@babel/generator@^7.7.2": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.6.tgz#9e1fca4811c77a10580d17d26b57b036133f3c2e" + integrity sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw== dependencies: - "@babel/types" "^7.23.0" + "@babel/types" "^7.23.6" "@jridgewell/gen-mapping" "^0.3.2" "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" -"@babel/helper-compilation-targets@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz#0698fc44551a26cf29f18d4662d5bf545a6cfc52" - integrity sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw== +"@babel/helper-compilation-targets@^7.23.6": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz#4d79069b16cbcf1461289eccfbbd81501ae39991" + integrity sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ== dependencies: - "@babel/compat-data" "^7.22.9" - "@babel/helper-validator-option" "^7.22.15" - browserslist "^4.21.9" + "@babel/compat-data" "^7.23.5" + "@babel/helper-validator-option" "^7.23.5" + browserslist "^4.22.2" lru-cache "^5.1.1" semver "^6.3.1" @@ -102,10 +92,10 @@ dependencies: "@babel/types" "^7.22.15" -"@babel/helper-module-transforms@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.20.tgz#da9edc14794babbe7386df438f3768067132f59e" - integrity sha512-dLT7JVWIUUxKOs1UnJUBR3S70YK+pKX6AbJgB2vMIvEkZkrfJDbYDJesnPshtKV4LhDOR3Oc5YULeDizRek+5A== +"@babel/helper-module-transforms@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz#d7d12c3c5d30af5b3c0fcab2a6d5217773e2d0f1" + integrity sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ== dependencies: "@babel/helper-environment-visitor" "^7.22.20" "@babel/helper-module-imports" "^7.22.15" @@ -132,48 +122,43 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-string-parser@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" - integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== +"@babel/helper-string-parser@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83" + integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== -"@babel/helper-validator-identifier@^7.22.19", "@babel/helper-validator-identifier@^7.22.20": +"@babel/helper-validator-identifier@^7.22.20": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== -"@babel/helper-validator-option@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040" - integrity sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA== +"@babel/helper-validator-option@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" + integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== -"@babel/helpers@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.15.tgz#f09c3df31e86e3ea0b7ff7556d85cdebd47ea6f1" - integrity sha512-7pAjK0aSdxOwR+CcYAqgWOGy5dcfvzsTIfFTb2odQqW47MDfv14UaJDY6eng8ylM2EaeKXdxaSWESbkmaQHTmw== +"@babel/helpers@^7.23.9": + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.9.tgz#c3e20bbe7f7a7e10cb9b178384b4affdf5995c7d" + integrity sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ== dependencies: - "@babel/template" "^7.22.15" - "@babel/traverse" "^7.22.15" - "@babel/types" "^7.22.15" + "@babel/template" "^7.23.9" + "@babel/traverse" "^7.23.9" + "@babel/types" "^7.23.9" -"@babel/highlight@^7.22.13": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" - integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== +"@babel/highlight@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" + integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== dependencies: "@babel/helper-validator-identifier" "^7.22.20" chalk "^2.4.2" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.22.16": - version "7.22.16" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.16.tgz#180aead7f247305cce6551bea2720934e2fa2c95" - integrity sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA== - -"@babel/parser@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719" - integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9": + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.9.tgz#7b903b6149b0f8fa7ad564af646c4c38a77fc44b" + integrity sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA== "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" @@ -260,52 +245,43 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-typescript@^7.7.2": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz#aac8d383b062c5072c647a31ef990c1d0af90272" - integrity sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz#24f460c85dbbc983cd2b9c4994178bcc01df958f" + integrity sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/template@^7.22.15", "@babel/template@^7.3.3": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" - integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== +"@babel/template@^7.22.15", "@babel/template@^7.23.9", "@babel/template@^7.3.3": + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.23.9.tgz#f881d0487cba2828d3259dcb9ef5005a9731011a" + integrity sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA== dependencies: - "@babel/code-frame" "^7.22.13" - "@babel/parser" "^7.22.15" - "@babel/types" "^7.22.15" + "@babel/code-frame" "^7.23.5" + "@babel/parser" "^7.23.9" + "@babel/types" "^7.23.9" -"@babel/traverse@^7.22.15", "@babel/traverse@^7.22.20", "@babel/traverse@^7.7.2": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.2.tgz#329c7a06735e144a506bdb2cad0268b7f46f4ad8" - integrity sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw== +"@babel/traverse@^7.23.9", "@babel/traverse@^7.7.2": + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.9.tgz#2f9d6aead6b564669394c5ce0f9302bb65b9d950" + integrity sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg== dependencies: - "@babel/code-frame" "^7.22.13" - "@babel/generator" "^7.23.0" + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.6" "@babel/helper-environment-visitor" "^7.22.20" "@babel/helper-function-name" "^7.23.0" "@babel/helper-hoist-variables" "^7.22.5" "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/parser" "^7.23.0" - "@babel/types" "^7.23.0" - debug "^4.1.0" + "@babel/parser" "^7.23.9" + "@babel/types" "^7.23.9" + debug "^4.3.1" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5", "@babel/types@^7.3.3": - version "7.22.19" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.19.tgz#7425343253556916e440e662bb221a93ddb75684" - integrity sha512-P7LAw/LbojPzkgp5oznjE6tQEIWbp4PkkfrZDINTro9zgBRtI324/EYsiSI7lhPbpIQ+DCeR2NNmMWANGGfZsg== +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.6", "@babel/types@^7.23.9", "@babel/types@^7.3.3": + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.9.tgz#1dd7b59a9a2b5c87f8b41e52770b5ecbf492e002" + integrity sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q== dependencies: - "@babel/helper-string-parser" "^7.22.5" - "@babel/helper-validator-identifier" "^7.22.19" - to-fast-properties "^2.0.0" - -"@babel/types@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.0.tgz#8c1f020c9df0e737e4e247c0619f58c68458aaeb" - integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg== - dependencies: - "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-string-parser" "^7.23.4" "@babel/helper-validator-identifier" "^7.22.20" to-fast-properties "^2.0.0" @@ -327,14 +303,14 @@ integrity sha512-rYn3Akp7teOkvqxguLbf6QKizH37Yeo33lseV+JHDZC19CsAV9wrrZM17Sa+LNEBj/hrYtQF7EIcllgGxhv9aw== "@bufbuild/protobuf@^1.3.0": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@bufbuild/protobuf/-/protobuf-1.3.1.tgz#c4de66bacbe7ac97fe054e68314aeba6f45177f9" - integrity sha512-BUyJWutgP2S8K/1NphOJokuwDckXS4qI2T1pGZAlkFdZchWae3jm6fCdkcGbLlM1QLOcNFFePd+7Feo4BYGrJQ== + version "1.7.2" + resolved "https://registry.yarnpkg.com/@bufbuild/protobuf/-/protobuf-1.7.2.tgz#1b3d6c66ebd987f7da7f1e3f0546cffaa87f8732" + integrity sha512-i5GE2Dk5ekdlK1TR7SugY4LWRrKSfb5T1Qn4unpIMbfxoeGKERKQ59HG3iYewacGD10SR7UzevfPnh6my4tNmQ== "@grpc/grpc-js@^1.4.4": - version "1.9.3" - resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.9.3.tgz#811cc49966ab7ed96efa31d213e80d671fd13839" - integrity sha512-b8iWtdrYIeT5fdZdS4Br/6h/kuk0PW5EVBUGk1amSbrpL8DlktJD43CdcCWwRdd6+jgwHhADSbL9CsNnm6EUPA== + version "1.9.14" + resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.9.14.tgz#236378822876cbf7903f9d61a0330410e8dcc5a1" + integrity sha512-nOpuzZ2G3IuMFN+UPPpKrC6NsLmWsTqSsm66IRfnBt1D4pwTqE27lmbpcPM+l2Ua4gE7PfjRHI6uedAy7hoXUw== dependencies: "@grpc/proto-loader" "^0.7.8" "@types/node" ">=12.12.47" @@ -604,9 +580,9 @@ integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.19" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz#f8a3249862f91be48d3127c3cfe992f79b4b8811" - integrity sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw== + version "0.3.22" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz#72a621e5de59f5f1ef792d0793a82ee20f645e4c" + integrity sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw== dependencies: "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" @@ -694,9 +670,9 @@ integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.2.tgz#215db4f4a35d710256579784a548907237728756" - integrity sha512-pNpr1T1xLUc2l3xJKuPtsEky3ybxN3m4fJkknfIpTCTfIZCDW57oAg+EfCgIIp2rvCe0Wn++/FfodDS4YXxBwA== + version "7.20.5" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" + integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== dependencies: "@babel/parser" "^7.20.7" "@babel/types" "^7.20.7" @@ -705,85 +681,87 @@ "@types/babel__traverse" "*" "@types/babel__generator@*": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.5.tgz#281f4764bcbbbc51fdded0f25aa587b4ce14da95" - integrity sha512-h9yIuWbJKdOPLJTbmSpPzkF67e659PbQDba7ifWm5BJ8xTv+sDmS7rFmywkWOvXedGTivCdeGSIIX8WLcRTz8w== + version "7.6.8" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.8.tgz#f836c61f48b1346e7d2b0d93c6dacc5b9535d3ab" + integrity sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw== dependencies: "@babel/types" "^7.0.0" "@types/babel__template@*": - version "7.4.2" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.2.tgz#843e9f1f47c957553b0c374481dc4772921d6a6b" - integrity sha512-/AVzPICMhMOMYoSx9MoKpGDKdBRsIXMNByh1PXSZoa+v6ZoLa8xxtsT/uLQ/NJm0XVAWl/BvId4MlDeXJaeIZQ== + version "7.4.4" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" + integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.2.tgz#4ddf99d95cfdd946ff35d2b65c978d9c9bf2645d" - integrity sha512-ojlGK1Hsfce93J0+kn3H5R73elidKUaZonirN33GSmgTUMpzI/MIFfSpF3haANe3G1bEBS9/9/QEqwTzwqFsKw== + version "7.20.5" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.5.tgz#7b7502be0aa80cc4ef22978846b983edaafcd4dd" + integrity sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ== dependencies: "@babel/types" "^7.20.7" "@types/google-protobuf@^3.15.5": - version "3.15.7" - resolved "https://registry.yarnpkg.com/@types/google-protobuf/-/google-protobuf-3.15.7.tgz#882e7351bc8ccf30bb21c507cc4597cf76f8888b" - integrity sha512-pIEMnb04J60c5eExVLUY/R4eWT5QEQ5cC792JOSfDI3kLjaKC4TjdgMp3xIrN1vxbi2Zk8LcscTm0VaNrIdniA== + version "3.15.12" + resolved "https://registry.yarnpkg.com/@types/google-protobuf/-/google-protobuf-3.15.12.tgz#eb2ba0eddd65712211a2b455dc6071d665ccf49b" + integrity sha512-40um9QqwHjRS92qnOaDpL7RmDK15NuZYo9HihiJRbYkMQZlWnuH8AdvbMy8/o6lgLmKbDUKa+OALCltHdbOTpQ== "@types/graceful-fs@^4.1.2": - version "4.1.7" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.7.tgz#30443a2e64fd51113bc3e2ba0914d47109695e2a" - integrity sha512-MhzcwU8aUygZroVwL2jeYk6JisJrPl/oov/gsgGCue9mkgl9wjGbzReYQClxiUgFDnib9FuHqTndccKeZKxTRw== + version "4.1.9" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" + integrity sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ== dependencies: "@types/node" "*" "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" - integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" + integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== "@types/istanbul-lib-report@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" - integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf" + integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== dependencies: "@types/istanbul-lib-coverage" "*" "@types/istanbul-reports@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" - integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54" + integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== dependencies: "@types/istanbul-lib-report" "*" "@types/jest@^29.0.0": - version "29.5.5" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.5.tgz#727204e06228fe24373df9bae76b90f3e8236a2a" - integrity sha512-ebylz2hnsWR9mYvmBFbXJXr+33UPc4+ZdxyDXh5w0FlPBTfCVN3wPL+kuOiQt3xvrK419v7XWeAs+AeOksafXg== + version "29.5.12" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.12.tgz#7f7dc6eb4cf246d2474ed78744b05d06ce025544" + integrity sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw== dependencies: expect "^29.0.0" pretty-format "^29.0.0" "@types/js-yaml@^4.0.5": - version "4.0.6" - resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.6.tgz#4b3afd5158b8749095b1f096967b6d0f838d862f" - integrity sha512-ACTuifTSIIbyksx2HTon3aFtCKWcID7/h3XEmRpDYdMCXxPbl+m9GteOJeaAkiAta/NJaSFuA7ahZ0NkwajDSw== + version "4.0.9" + resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.9.tgz#cd82382c4f902fed9691a2ed79ec68c5898af4c2" + integrity sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg== "@types/node@*", "@types/node@>=12.12.47", "@types/node@>=13.7.0": - version "20.6.3" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.6.3.tgz#5b763b321cd3b80f6b8dde7a37e1a77ff9358dd9" - integrity sha512-HksnYH4Ljr4VQgEy2lTStbCKv/P590tmPe5HqOnv9Gprffgv5WXAY+Y5Gqniu0GGqeTCUdBnzC3QSrzPkBkAMA== + version "20.11.16" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.16.tgz#4411f79411514eb8e2926f036c86c9f0e4ec6708" + integrity sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ== + dependencies: + undici-types "~5.26.4" "@types/node@^16.11.11": - version "16.18.53" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.53.tgz#21820fe4d5968aaf8071dabd1ee13d24ada1350a" - integrity sha512-vVmHeo4tpF8zsknALU90Hh24VueYdu45ZlXzYWFbom61YR4avJqTFDC3QlWzjuTdAv6/3xHaxiO9NrtVZXrkmw== + version "16.18.79" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.79.tgz#153e25561b271cf87dc1b28d38f98cebd514d788" + integrity sha512-Qd7jdLR5zmnIyMhfDrfPqN5tUCvreVpP3Qrf2oSM+F7SNzlb/MwHISGUkdFHtevfkPJ3iAGyeQI/jsbh9EStgQ== "@types/path-browserify@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/path-browserify/-/path-browserify-1.0.0.tgz#294ec6e88b6b0d340a3897b7120e5b393f16690e" - integrity sha512-XMCcyhSvxcch8b7rZAtFAaierBYdeHXVvg2iYnxOV0MCQHmPuRRmGZPFDRzPayxcGiiSL1Te9UIO+f3cuj0tfw== + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/path-browserify/-/path-browserify-1.0.2.tgz#14b62d4371316016f254b9cca5c10e60ef33dcc0" + integrity sha512-ZkC5IUqqIFPXx3ASTTybTzmQdwHwe2C0u3eL75ldQ6T9E9IWFJodn6hIfbZGab73DfyiHN4Xw15gNxUq2FbvBA== "@types/prettier@^2.1.5": version "2.7.3" @@ -791,36 +769,36 @@ integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== "@types/semver@^7.3.9": - version "7.5.2" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.2.tgz#31f6eec1ed7ec23f4f05608d3a2d381df041f564" - integrity sha512-7aqorHYgdNO4DM36stTiGO3DvKoex9TQRwsJU6vMaFGyqpBA1MNZkz+PG3gaNUPpTAOYhT1WR7M1JyA3fbS9Cw== + version "7.5.6" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.6.tgz#c65b2bfce1bec346582c07724e3f8c1017a20339" + integrity sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A== "@types/stack-utils@^2.0.0": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" - integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" + integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== "@types/utf8@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/utf8/-/utf8-3.0.1.tgz#bf081663d4fff05ee63b41f377a35f8b189f7e5b" - integrity sha512-1EkWuw7rT3BMz2HpmcEOr/HL61mWNA6Ulr/KdbXR9AI0A55wD4Qfv8hizd8Q1DnknSIzzDvQmvvY/guvX7jjZA== + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/utf8/-/utf8-3.0.3.tgz#e153ada15157477a9e0d2bcc638c34284a1d82ea" + integrity sha512-+lqLGxWZsEe4Z6OrzBI7Ym4SMUTaMS5yOrHZ0/IL0bpIye1Qbs4PpobJL2mLDbftUXlPFZR7fu6d1yM+bHLX1w== "@types/yargs-parser@*": - version "21.0.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" - integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== + version "21.0.3" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" + integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== "@types/yargs@^16.0.0": - version "16.0.5" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.5.tgz#12cc86393985735a283e387936398c2f9e5f88e3" - integrity sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ== + version "16.0.9" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.9.tgz#ba506215e45f7707e6cbcaf386981155b7ab956e" + integrity sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA== dependencies: "@types/yargs-parser" "*" "@types/yargs@^17.0.8": - version "17.0.24" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.24.tgz#b3ef8d50ad4aa6aecf6ddc97c580a00f5aa11902" - integrity sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw== + version "17.0.32" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.32.tgz#030774723a2f7faafebf645f4e5a48371dca6229" + integrity sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog== dependencies: "@types/yargs-parser" "*" @@ -848,9 +826,9 @@ acorn@^7.1.1: integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== acorn@^8.2.4: - version "8.10.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" - integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + version "8.11.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" + integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== agent-base@6: version "6.0.2" @@ -1013,15 +991,15 @@ browser-process-hrtime@^1.0.0: resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== -browserslist@^4.21.9: - version "4.21.10" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.10.tgz#dbbac576628c13d3b2231332cb2ec5a46e015bb0" - integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ== +browserslist@^4.22.2: + version "4.22.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.3.tgz#299d11b7e947a6b843981392721169e27d60c5a6" + integrity sha512-UAp55yfwNv0klWNapjs/ktHoguxuQNGnOzxYmfnXIS+8AsRDZkSDxg7R1AX3GKzn078SBI5dzwzj/Yx0Or0e3A== dependencies: - caniuse-lite "^1.0.30001517" - electron-to-chromium "^1.4.477" - node-releases "^2.0.13" - update-browserslist-db "^1.0.11" + caniuse-lite "^1.0.30001580" + electron-to-chromium "^1.4.648" + node-releases "^2.0.14" + update-browserslist-db "^1.0.13" bs-logger@0.x: version "0.2.6" @@ -1057,10 +1035,10 @@ camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001517: - version "1.0.30001538" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001538.tgz#9dbc6b9af1ff06b5eb12350c2012b3af56744f3f" - integrity sha512-HWJnhnID+0YMtGlzcp3T9drmBJUVDchPJ08tpUGFLs9CYlwWPH2uLgpHn8fND5pCgXVtnGS3H4QR9XLMHVNkHw== +caniuse-lite@^1.0.30001580: + version "1.0.30001583" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001583.tgz#abb2970cc370801dc7e27bf290509dc132cfa390" + integrity sha512-acWTYaha8xfhA/Du/z4sNZjHUWjkiuoAi2LM+T/aL+kemKQgPT1xBb/YKjlQ0Qo8gvbHsGNplrEJ+9G3gL7i4Q== chalk@^2.4.2: version "2.4.2" @@ -1090,9 +1068,9 @@ chownr@^2.0.0: integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== ci-info@^3.2.0: - version "3.8.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" - integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== + version "3.9.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" + integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== cjs-module-lexer@^1.0.0: version "1.2.3" @@ -1163,11 +1141,16 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: +convert-source-map@^1.4.0, convert-source-map@^1.6.0: version "1.9.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -1203,7 +1186,7 @@ data-urls@^2.0.0: whatwg-mimetype "^2.3.0" whatwg-url "^8.0.0" -debug@4, debug@^4.1.0, debug@^4.1.1: +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -1252,10 +1235,10 @@ domexception@^2.0.1: dependencies: webidl-conversions "^5.0.0" -electron-to-chromium@^1.4.477: - version "1.4.526" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.526.tgz#1bcda5f2b8238e497c20fcdb41af5da907a770e2" - integrity sha512-tjjTMjmZAx1g6COrintLTa2/jcafYKxKoiEkdQOrVdbLaHh2wCt2nsAF8ZHweezkrP+dl/VG9T5nabcYoo0U5Q== +electron-to-chromium@^1.4.648: + version "1.4.655" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.655.tgz#112410db0d7f9c2b4ed8baa3b1b548522a6f89d4" + integrity sha512-2yszojF7vIZ68adIOvzV4bku8OZad9w5H9xF3ZAMZjPuOjBarlflUkjN6DggdV+L71WZuKUfKUhov/34+G5QHg== emittery@^0.8.1: version "0.8.1" @@ -1404,9 +1387,9 @@ find-up@^4.0.0, find-up@^4.1.0: path-exists "^4.0.0" follow-redirects@^1.14.4: - version "1.15.4" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf" - integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw== + version "1.15.5" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.5.tgz#54d4d6d062c0fa7d9d17feb008461550e3ba8020" + integrity sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw== form-data@^3.0.0: version "3.0.1" @@ -1434,10 +1417,10 @@ fsevents@^2.3.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== gensync@^1.0.0-beta.2: version "1.0.0-beta.2" @@ -1487,9 +1470,9 @@ graceful-fs@^4.2.9: integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== grpc-web@^1.3.0, grpc-web@^1.3.1: - version "1.4.2" - resolved "https://registry.yarnpkg.com/grpc-web/-/grpc-web-1.4.2.tgz#86995f76471ce6b2119106ec26f909b7b69e7d43" - integrity sha512-gUxWq42l5ldaRplcKb4Pw5O4XBONWZgz3vxIIXnfIeJj8Jc3wYiq2O4c9xzx/NGbbPEej4rhI62C9eTENwLGNw== + version "1.5.0" + resolved "https://registry.yarnpkg.com/grpc-web/-/grpc-web-1.5.0.tgz#154e4007ab59a94bf7726b87ef6c5bd8815ecf6e" + integrity sha512-y1tS3BBIoiVSzKTDF3Hm7E8hV2n7YY7pO0Uo7depfWJqKzWE+SKr0jvHNIJsJJYILQlpYShpi/DRJJMbosgDMQ== has-flag@^3.0.0: version "3.0.0" @@ -1501,12 +1484,12 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== +hasown@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" + integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== dependencies: - function-bind "^1.1.1" + function-bind "^1.1.2" html-encoding-sniffer@^2.0.1: version "2.0.1" @@ -1581,11 +1564,11 @@ is-arrayish@^0.2.1: integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== is-core-module@^2.13.0: - version "2.13.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" - integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + version "2.13.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== dependencies: - has "^1.0.3" + hasown "^2.0.0" is-fullwidth-code-point@^3.0.0: version "3.0.0" @@ -1623,9 +1606,9 @@ isexe@^2.0.0: integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" - integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + version "3.2.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" + integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: version "5.2.1" @@ -2207,7 +2190,7 @@ kleur@^3.0.3: integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== kurtosis-sdk@../../api/typescript: - version "0.86.1" + version "0.86.12" dependencies: "@bufbuild/connect" "^0.12.0" "@bufbuild/connect-web" "^0.12.0" @@ -2260,9 +2243,9 @@ lodash@^4.7.0: integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== loglevel@^1.7.1, loglevel@^1.8.0: - version "1.8.1" - resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.8.1.tgz#5c621f83d5b48c54ae93b6156353f555963377b4" - integrity sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg== + version "1.9.1" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.9.1.tgz#d63976ac9bcd03c7c873116d41c2a85bafff1be7" + integrity sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg== long@^5.0.0: version "5.2.3" @@ -2384,10 +2367,10 @@ node-int64@^0.4.0: resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== -node-releases@^2.0.13: - version "2.0.13" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" - integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== +node-releases@^2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" + integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== normalize-path@^3.0.0: version "3.0.0" @@ -2528,9 +2511,9 @@ prompts@^2.0.1: sisteransi "^1.0.5" protobufjs@^7.2.4: - version "7.2.5" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.5.tgz#45d5c57387a6d29a17aab6846dcc283f9b8e7f2d" - integrity sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A== + version "7.2.6" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.6.tgz#4a0ccd79eb292717aacf07530a07e0ed20278215" + integrity sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw== dependencies: "@protobufjs/aspromise" "^1.1.2" "@protobufjs/base64" "^1.1.2" @@ -2551,9 +2534,9 @@ psl@^1.1.33: integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== punycode@^2.1.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== querystringify@^2.1.1: version "2.2.0" @@ -2598,9 +2581,9 @@ resolve.exports@^1.1.0: integrity sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ== resolve@^1.20.0: - version "1.22.6" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.6.tgz#dd209739eca3aef739c626fea1b4f3c506195362" - integrity sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw== + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== dependencies: is-core-module "^2.13.0" path-parse "^1.0.7" @@ -2876,12 +2859,17 @@ typescript@^4.5.2: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + universalify@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== -update-browserslist-db@^1.0.11: +update-browserslist-db@^1.0.13: version "1.0.13" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== diff --git a/readme-static-files/goland-apic-breakpoint.png b/readme-static-files/goland-apic-breakpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..2f6f40580bde00100a332b473b93fae52d16ea65 GIT binary patch literal 44240 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 z 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 et6bSVP-4F-T%ZT#hy70gNBut?&2 + show_helptext_and_exit +fi + + +# ================================================================================================== +# Main Logic +# ================================================================================================== +apic_namespace_name="${KURTOSIS_KUBERNETES_NAMESPACE_PREFIX}-${enclave_name}" + +get_apic_pod_name_cmd="kubectl get pods -l="${APIC_CONTAINER_K8S_LABEL}" -n ${apic_namespace_name} | cut -d ' ' -f 1 | tail -n +2" + +# execute the port forward to the debug server inside the APIC's container +kubectl port-forward -n "${apic_namespace_name}" $(eval "${get_apic_pod_name_cmd}") ${APIC_DEBUG_SERVER_PORT}:${APIC_DEBUG_SERVER_PORT}