| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| syntax = "proto2"; |
| |
| import "mesos/mesos.proto"; |
| |
| package mesos.agent; |
| |
| option java_package = "org.apache.mesos.agent"; |
| option java_outer_classname = "Protos"; |
| |
| /** |
| * Calls that can be sent to the agent API. |
| * |
| * A call is described using the standard protocol buffer "union" |
| * trick, see |
| * https://developers.google.com/protocol-buffers/docs/techniques#union. |
| */ |
| message Call { |
| // If a call of type `Call::FOO` requires additional parameters they can be |
| // included in the corresponding `Call::Foo` message. Similarly, if a call |
| // receives a synchronous response it will be returned as a `Response` |
| // message of type `Response::FOO`; see `Call::LaunchNestedContainerSession` |
| // and `Call::AttachContainerOutput` for exceptions. |
| enum Type { |
| UNKNOWN = 0; |
| |
| GET_HEALTH = 1; // Retrieves the agent's health status. |
| GET_FLAGS = 2; // Retrieves the agent's flag configuration. |
| GET_VERSION = 3; // Retrieves the agent's version information. |
| GET_METRICS = 4; // See 'GetMetrics' below. |
| |
| GET_LOGGING_LEVEL = 5; // Retrieves the agent's logging level. |
| SET_LOGGING_LEVEL = 6; // See 'SetLoggingLevel' below. |
| |
| LIST_FILES = 7; |
| READ_FILE = 8; // See 'ReadFile' below. |
| |
| GET_STATE = 9; |
| |
| GET_CONTAINERS = 10; |
| |
| // Retrieves the information about known frameworks. |
| GET_FRAMEWORKS = 11; |
| |
| // Retrieves the information about known executors. |
| GET_EXECUTORS = 12; |
| |
| // Retrieves the information about known operations. |
| GET_OPERATIONS = 31; |
| |
| // Retrieves the information about known tasks. |
| GET_TASKS = 13; |
| |
| // Retrieves the agent information. |
| GET_AGENT = 20; |
| |
| // Retrieves the information about known resource providers. |
| GET_RESOURCE_PROVIDERS = 26; |
| |
| // Calls for managing nested containers underneath an executor's container. |
| // Some of these calls are deprecated in favor of the calls |
| // for both standalone or nested containers further below. |
| LAUNCH_NESTED_CONTAINER = 14 [deprecated = true]; |
| WAIT_NESTED_CONTAINER = 15 [deprecated = true]; |
| KILL_NESTED_CONTAINER = 16 [deprecated = true]; |
| REMOVE_NESTED_CONTAINER = 21 [deprecated = true]; |
| |
| // See 'LaunchNestedContainerSession' below. |
| LAUNCH_NESTED_CONTAINER_SESSION = 17; |
| |
| ATTACH_CONTAINER_INPUT = 18; // See 'AttachContainerInput' below. |
| ATTACH_CONTAINER_OUTPUT = 19; // see 'AttachContainerOutput' below. |
| |
| // Calls for managing standalone containers |
| // or containers nested underneath another container. |
| LAUNCH_CONTAINER = 22; // See 'LaunchContainer' below. |
| WAIT_CONTAINER = 23; // See 'WaitContainer' below. |
| KILL_CONTAINER = 24; // See 'KillContainer' below. |
| REMOVE_CONTAINER = 25; // See 'RemoveContainer' below. |
| |
| ADD_RESOURCE_PROVIDER_CONFIG = 27; // See 'AddResourceProviderConfig' below. // NOLINT |
| UPDATE_RESOURCE_PROVIDER_CONFIG = 28; // See 'UpdateResourceProviderConfig' below. // NOLINT |
| REMOVE_RESOURCE_PROVIDER_CONFIG = 29; // See 'RemoveResourceProviderConfig' below. // NOLINT |
| |
| MARK_RESOURCE_PROVIDER_GONE = 32; // See 'MarkResourceProviderGone' below. |
| |
| // Prune unused container images. |
| PRUNE_IMAGES = 30; |
| } |
| |
| // Provides a snapshot of the current metrics tracked by the agent. |
| message GetMetrics { |
| // If set, `timeout` would be used to determines the maximum amount of time |
| // the API will take to respond. If the timeout is exceeded, some metrics |
| // may not be included in the response. |
| optional DurationInfo timeout = 1; |
| } |
| |
| // Sets the logging verbosity level for a specified duration. Mesos uses |
| // [glog](https://github.com/google/glog) for logging. The library only uses |
| // verbose logging which means nothing will be output unless the verbosity |
| // level is set (by default it's 0, libprocess uses levels 1, 2, and 3). |
| message SetLoggingLevel { |
| // The verbosity level. |
| required uint32 level = 1; |
| // The duration to keep verbosity level toggled. After this duration, the |
| // verbosity level of log would revert to the original level. |
| required DurationInfo duration = 2; |
| } |
| |
| // Provides the file listing for a directory. |
| message ListFiles { |
| required string path = 1; |
| } |
| |
| // Reads data from a file. |
| message ReadFile { |
| // The path of file. |
| required string path = 1; |
| |
| // Initial offset in file to start reading from. |
| required uint64 offset = 2; |
| |
| // The maximum number of bytes to read. The read length is capped at 16 |
| // memory pages. |
| optional uint64 length = 3; |
| } |
| |
| // Lists active containers on the agent. |
| message GetContainers { |
| optional bool show_nested = 1; |
| optional bool show_standalone = 2; |
| } |
| |
| // Deprecated in favor of `LaunchContainer`. |
| message LaunchNestedContainer { |
| required ContainerID container_id = 1; |
| optional CommandInfo command = 2; |
| optional ContainerInfo container = 3; |
| } |
| |
| // Deprecated in favor of `WaitContainer`. |
| message WaitNestedContainer { |
| required ContainerID container_id = 1; |
| } |
| |
| // Deprecated in favor of `KillContainer`. |
| message KillNestedContainer { |
| required ContainerID container_id = 1; |
| optional int32 signal = 2; |
| } |
| |
| // Deprecated in favor of `RemoveContainer`. |
| message RemoveNestedContainer { |
| required ContainerID container_id = 1; |
| } |
| |
| // Launches a nested container within an executor's tree of containers. |
| // The differences between this call and `LaunchNestedContainer` are: |
| // 1) The container's life-cycle is tied to the lifetime of the |
| // connection used to make this call, i.e., if the connection ever |
| // breaks, the container will be destroyed. |
| // 2) The nested container shares the same namespaces and cgroups as |
| // its parent container. |
| // 3) Results in a streaming response of type `ProcessIO`. So the call |
| // needs to be made on a persistent connection. |
| message LaunchNestedContainerSession { |
| required ContainerID container_id = 1; |
| optional CommandInfo command = 2; |
| optional ContainerInfo container = 3; |
| } |
| |
| // Attaches the caller to the STDIN of the entry point of the container. |
| // Clients can use this to stream input data to a container. |
| // Note that this call needs to be made on a persistent connection by |
| // streaming a CONTAINER_ID message followed by one or more PROCESS_IO |
| // messages. |
| message AttachContainerInput { |
| enum Type { |
| UNKNOWN = 0; |
| CONTAINER_ID = 1; |
| PROCESS_IO = 2; |
| } |
| |
| optional Type type = 1; |
| optional ContainerID container_id = 2; |
| optional ProcessIO process_io = 3; |
| } |
| |
| // Attaches the caller to the STDOUT and STDERR of the entrypoint of |
| // the container. Clients can use this to stream output/error from the |
| // container. This call will result in a streaming response of `ProcessIO`; |
| // so this call needs to be made on a persistent connection. |
| message AttachContainerOutput { |
| required ContainerID container_id = 1; |
| } |
| |
| // Launches a either a "standalone" container on this agent |
| // or a nested container within another tree of containers. |
| // |
| // A standalone container is launched by specifying a ContainerID |
| // with no parent. Standalone containers bypass the normal offer cycle |
| // between the master and agent. Unlike other containers, a standalone |
| // container does not have an executor or any tasks. This means the |
| // standalone container does not report back to Mesos or any framework |
| // and must be supervised separately. |
| // |
| // A nested container is launched by specifying a ContainerID with |
| // another existing container (including standalone containers) |
| // as the parent. |
| // |
| // Returns 200 OK if the new container launch succeeds. |
| // Returns 202 Accepted if the requested ContainerID is already in use |
| // by a standalone or nested container. |
| // Returns 400 Bad Request if the container launch fails. |
| message LaunchContainer { |
| // NOTE: Some characters cannot be used in the ID. All characters |
| // must be valid filesystem path characters. In addition, '/' and '.' |
| // are reserved. |
| required ContainerID container_id = 1; |
| |
| optional CommandInfo command = 2; |
| |
| // NOTE: Nested containers may not specify resources and instead |
| // share resources with its parent container. |
| // |
| // TODO(josephw): These resources are purely used for isolation |
| // and are not accounted for by the Mesos master (if connected). |
| // It is the caller's responsibility to ensure that resources are |
| // not overcommitted (e.g. CPU and memory) or conflicting (e.g. ports |
| // and volumes). Once there is support for preempting tasks and a |
| // way to update the resources advertised by the agent, these standalone |
| // container resources should be accounted for by the master. |
| repeated Resource resources = 3; |
| |
| optional ContainerInfo container = 4; |
| |
| // Resource limits associated with the container during launch. |
| map<string, Value.Scalar> limits = 5; |
| } |
| |
| // Waits for the standalone or nested container to terminate |
| // and returns the exit status. |
| // |
| // Returns 200 OK if and when the container exits. |
| // Returns 404 Not Found if the container does not exist. |
| message WaitContainer { |
| required ContainerID container_id = 1; |
| } |
| |
| // Kills the standalone or nested container. The signal to be sent |
| // to the container can be specified in the 'signal' field. |
| // |
| // Returns 200 OK if the signal is sent successfully. |
| // Returns 404 Not Found if the container does not exist. |
| message KillContainer { |
| required ContainerID container_id = 1; |
| |
| // Defaults to SIGKILL. |
| optional int32 signal = 2; |
| } |
| |
| // Removes a container's artifacts (runtime and sandbox directories). |
| // |
| // For nested containers, it is important to use this call if multiple |
| // nested containers are launched under the same parent container, because |
| // garbage collection only takes place at the parent container. Artifacts |
| // belonging to nested containers will not be garbage collected while |
| // the parent container is running. |
| // |
| // TODO(josephw): A standalone container's runtime directory is currently |
| // garbage collected as soon as the container exits. To allow the user to |
| // retrieve the exit status reliably, the runtime directory cannot be |
| // garbage collected immediately. Instead, the user will eventually be |
| // required to make this call after the standalone container has exited. |
| // Also, a standalone container's sandbox directory is currently not |
| // garbage collected and is only deleted via this call. |
| // |
| // Returns 200 OK if the removal is successful or if the parent container |
| // (for nested containers) does not exist. |
| // Returns 500 Internal Server Error if anything goes wrong, including |
| // if the container is still running or does not exist. |
| // |
| // TODO(josephw): Consider returning a 400 Bad Request instead of 500 |
| // Internal Server Error when the user tries to remove a running or |
| // nonexistent nested container. |
| message RemoveContainer { |
| required ContainerID container_id = 1; |
| } |
| |
| // Adds a new resource provider config file. |
| // |
| // The content of the `info` field will be written into a new config file in |
| // the resource provider config directory, and a new resource provider will be |
| // launched asynchronously based on the config. Callers must not set the |
| // `info.id` field. This call is idempotent, so if a config file identical to |
| // the content of the `info` field already exists, this call will return |
| // without launching a resource provider. Note that if a config file is |
| // placed into the resource provider config directory out-of-band after the |
| // agent starts up, it will not be checked against this call. |
| // |
| // Returns 200 OK if a new config file is created, or an identical config file |
| // exists. |
| // Returns 400 Bad Request if `info` is not well-formed. |
| // Returns 403 Forbidden if the call is not authorized. |
| // Returns 409 Conflict if another config file that describes a resource |
| // provider of the same type and name exists, but the content is not |
| // identical. |
| // Returns 500 Internal Server Error if anything goes wrong. |
| // |
| // NOTE: For the time being, this API is subject to change and the related |
| // feature is experimental. |
| message AddResourceProviderConfig { |
| required ResourceProviderInfo info = 1; |
| } |
| |
| // Updates an existing resource provider config file. |
| // |
| // The content of the `info` field will be written into an existing config |
| // file that describes a resource provider of the specified type and name in |
| // the resource provider config directory, and the corresponding resource |
| // provider will be relaunched asynchronously to reflect the changes in the |
| // config. Callers must not set the `info.id` field. This call is idempotent, |
| // so if there is no change in the config, this call will return without |
| // relaunching the resource provider. Note that if a config file is placed |
| // into the resource provider config directory out-of-band after the agent |
| // starts up, it will not be checked against this call. |
| // |
| // Returns 200 OK if an existing config file is updated, or there is no change |
| // in the config file. |
| // Returns 400 Bad Request if `info` is not well-formed. |
| // Returns 403 Forbidden if the call is not authorized. |
| // Returns 409 Conflict if no config file describes a resource provider of the |
| // same type and name exists. |
| // Returns 500 Internal Server Error if anything goes wrong. |
| // |
| // NOTE: For the time being, this API is subject to change and the related |
| // feature is experimental. |
| message UpdateResourceProviderConfig { |
| required ResourceProviderInfo info = 1; |
| } |
| |
| // Removes a config file from the resource provider config directory. |
| // |
| // The config file that describes the resource provider of the specified type |
| // and name will be removed, and the corresponding resource provider will be |
| // terminated asynchronously. This call is idempotent, so if no matching |
| // config file exists, this call will return without terminating any resource |
| // provider. Note that if a config file is placed into the resource provider |
| // config directory out-of-band after the agent starts up, it will not be |
| // checked against this call. |
| // |
| // Returns 200 OK if the config file is removed, or no matching config file |
| // exists. |
| // Returns 403 Forbidden if the call is not authorized. |
| // Returns 500 Internal Server Error if anything goes wrong. |
| // |
| // NOTE: For the time being, this API is subject to change and the related |
| // feature is experimental. |
| message RemoveResourceProviderConfig { |
| required string type = 1; |
| required string name = 2; |
| } |
| |
| // Mark a resource provider as gone. |
| message MarkResourceProviderGone { |
| required ResourceProviderID resource_provider_id = 1; |
| } |
| |
| // Prune unused container images from image store. |
| // |
| // Images and layers referenced by active containers as well as |
| // image references specified in `excluded_images` will not be pruned. |
| message PruneImages { |
| repeated Image excluded_images = 1; |
| } |
| |
| optional Type type = 1; |
| |
| optional GetMetrics get_metrics = 2; |
| optional SetLoggingLevel set_logging_level = 3; |
| optional ListFiles list_files = 4; |
| optional ReadFile read_file = 5; |
| |
| optional GetContainers get_containers = 20; |
| |
| optional LaunchNestedContainer launch_nested_container = 6 |
| [deprecated = true]; |
| |
| optional WaitNestedContainer wait_nested_container = 7 [deprecated = true]; |
| optional KillNestedContainer kill_nested_container = 8 [deprecated = true]; |
| optional RemoveNestedContainer remove_nested_container = 12 |
| [deprecated = true]; |
| |
| optional LaunchNestedContainerSession launch_nested_container_session = 9; |
| optional AttachContainerInput attach_container_input = 10; |
| optional AttachContainerOutput attach_container_output = 11; |
| optional LaunchContainer launch_container = 13; |
| optional WaitContainer wait_container = 14; |
| optional KillContainer kill_container = 15; |
| optional RemoveContainer remove_container = 16; |
| |
| optional AddResourceProviderConfig add_resource_provider_config = 17; |
| optional UpdateResourceProviderConfig update_resource_provider_config = 18; |
| optional RemoveResourceProviderConfig remove_resource_provider_config = 19; |
| |
| optional MarkResourceProviderGone mark_resource_provider_gone = 22; |
| |
| optional PruneImages prune_images = 21; |
| } |
| |
| |
| /** |
| * Synchronous responses for all calls made to the agent API. |
| */ |
| message Response { |
| // Each of the responses of type `FOO` corresponds to `Foo` message below. |
| enum Type { |
| UNKNOWN = 0; |
| |
| GET_HEALTH = 1; // See 'GetHealth' below. |
| GET_FLAGS = 2; // See 'GetFlags' below. |
| GET_VERSION = 3; // See 'GetVersion' below. |
| GET_METRICS = 4; // See 'GetMetrics' below. |
| |
| GET_LOGGING_LEVEL = 5; // See 'GetLoggingLevel' below. |
| |
| LIST_FILES = 6; |
| READ_FILE = 7; // See 'ReadFile' below. |
| |
| GET_STATE = 8; |
| |
| GET_CONTAINERS = 9; |
| GET_FRAMEWORKS = 10; // See 'GetFrameworks' below. |
| GET_EXECUTORS = 11; // See 'GetExecutors' below. |
| GET_OPERATIONS = 17; // See 'GetOperations' below. |
| GET_TASKS = 12; // See 'GetTasks' below. |
| GET_AGENT = 14; // See 'GetAgent' below. |
| GET_RESOURCE_PROVIDERS = 16; // See 'GetResourceProviders' below. |
| |
| WAIT_NESTED_CONTAINER = 13 [deprecated = true]; |
| WAIT_CONTAINER = 15; // See 'WaitContainer' below. |
| } |
| |
| // `healthy` would be true if the agent is healthy. Delayed responses are also |
| // indicative of the poor health of the agent. |
| message GetHealth { |
| required bool healthy = 1; |
| } |
| |
| // Contains the flag configuration of the agent. |
| message GetFlags { |
| repeated Flag flags = 1; |
| } |
| |
| // Contains the version information of the agent. |
| message GetVersion { |
| required VersionInfo version_info = 1; |
| } |
| |
| // Contains a snapshot of the current metrics. |
| message GetMetrics { |
| repeated Metric metrics = 1; |
| } |
| |
| // Contains the logging level of the agent. |
| message GetLoggingLevel { |
| required uint32 level = 1; |
| } |
| |
| // Contains the file listing(similar to `ls -l`) for a directory. |
| message ListFiles { |
| repeated FileInfo file_infos = 1; |
| } |
| |
| // Contains the file data. |
| message ReadFile { |
| // The size of file (in bytes). |
| required uint64 size = 1; |
| |
| required bytes data = 2; |
| } |
| |
| // Contains full state of the agent i.e. information about the tasks, |
| // frameworks and executors running in the cluster. |
| message GetState { |
| optional GetTasks get_tasks = 1; |
| optional GetExecutors get_executors = 2; |
| optional GetFrameworks get_frameworks = 3; |
| } |
| |
| // Information about containers running on this agent. It contains |
| // ContainerStatus and ResourceStatistics along with some metadata |
| // of the containers. |
| message GetContainers { |
| message Container { |
| optional FrameworkID framework_id = 1; |
| optional ExecutorID executor_id = 2; |
| optional string executor_name = 3; |
| required ContainerID container_id = 4; |
| optional ContainerStatus container_status = 5; |
| optional ResourceStatistics resource_statistics = 6; |
| } |
| |
| repeated Container containers = 1; |
| } |
| |
| // Information about all the frameworks known to the agent at the current |
| // time. |
| message GetFrameworks { |
| message Framework { |
| required FrameworkInfo framework_info = 1; |
| } |
| |
| repeated Framework frameworks = 1; |
| repeated Framework completed_frameworks = 2; |
| } |
| |
| // Lists information about all the executors known to the agent at the |
| // current time. |
| message GetExecutors { |
| message Executor { |
| required ExecutorInfo executor_info = 1; |
| } |
| |
| repeated Executor executors = 1; |
| repeated Executor completed_executors = 2; |
| } |
| |
| // Lists information about all operations known to the agent at the |
| // current time. |
| message GetOperations { |
| repeated Operation operations = 1; |
| } |
| |
| // Lists information about all the tasks known to the agent at the current |
| // time. |
| message GetTasks { |
| // Tasks that are pending in the agent's queue before an executor is |
| // launched. |
| repeated Task pending_tasks = 1; |
| |
| // Tasks that are enqueued for a launched executor that has not yet |
| // registered. |
| repeated Task queued_tasks = 2; |
| |
| // Tasks that are running. |
| repeated Task launched_tasks = 3; |
| |
| // Tasks that are terminated but pending updates. |
| repeated Task terminated_tasks = 4; |
| |
| // Tasks that are terminated and updates acked. |
| repeated Task completed_tasks = 5; |
| } |
| |
| // Contains the agent's information. |
| message GetAgent { |
| optional SlaveInfo slave_info = 1; |
| |
| optional DrainConfig drain_config = 2; |
| optional TimeInfo estimated_drain_start_time = 3; |
| } |
| |
| // Lists information about all resource providers known to the agent |
| // at the current time. |
| message GetResourceProviders { |
| message ResourceProvider { |
| required ResourceProviderInfo resource_provider_info = 1; |
| repeated Resource total_resources = 2; |
| } |
| |
| repeated ResourceProvider resource_providers = 1; |
| } |
| |
| // Returns termination information about the nested container. |
| message WaitNestedContainer { |
| // Wait status of the lead process in the container. Note that this |
| // is the return value of `wait(2)`, so callers must use the `wait(2)` |
| // family of macros to extract whether the process exited cleanly and |
| // what the exit code was. |
| optional int32 exit_status = 1; |
| |
| // The `state` and `reason` fields may be populated if the Mesos agent |
| // terminates the container. In the absence of any special knowledge, |
| // executors should propagate this information via the `status` field |
| // of an `Update` call for the corresponding TaskID. |
| optional TaskState state = 2; |
| optional TaskStatus.Reason reason = 3; |
| |
| // This field will be populated if the task was terminated due to |
| // a resource limitation. |
| optional TaskResourceLimitation limitation = 4; |
| |
| optional string message = 5; |
| } |
| |
| // Returns termination information about the standalone or nested container. |
| message WaitContainer { |
| // Wait status of the lead process in the container. Note that this |
| // is the return value of `wait(2)`, so callers must use the `wait(2)` |
| // family of macros to extract whether the process exited cleanly and |
| // what the exit code was. |
| optional int32 exit_status = 1; |
| |
| // The `state` and `reason` fields may be populated if the Mesos agent |
| // terminates the container. In the absence of any special knowledge, |
| // executors should propagate this information via the `status` field |
| // of an `Update` call for the corresponding TaskID. |
| optional TaskState state = 2; |
| optional TaskStatus.Reason reason = 3; |
| |
| // This field will be populated if the task was terminated due to |
| // a resource limitation. |
| optional TaskResourceLimitation limitation = 4; |
| |
| optional string message = 5; |
| } |
| |
| optional Type type = 1; |
| |
| optional GetHealth get_health = 2; |
| optional GetFlags get_flags = 3; |
| optional GetVersion get_version = 4; |
| optional GetMetrics get_metrics = 5; |
| optional GetLoggingLevel get_logging_level = 6; |
| optional ListFiles list_files = 7; |
| optional ReadFile read_file = 8; |
| optional GetState get_state = 9; |
| optional GetContainers get_containers = 10; |
| optional GetFrameworks get_frameworks = 11; |
| optional GetExecutors get_executors = 12; |
| optional GetOperations get_operations = 18; |
| optional GetTasks get_tasks = 13; |
| optional GetAgent get_agent = 15; |
| optional GetResourceProviders get_resource_providers = 17; |
| optional WaitNestedContainer wait_nested_container = 14; |
| optional WaitContainer wait_container = 16; |
| } |
| |
| |
| /** |
| * Streaming response to `Call::LAUNCH_NESTED_CONTAINER_SESSION` and |
| * `Call::ATTACH_CONTAINER_OUTPUT`. |
| * |
| * This message is also used to stream request data for |
| * `Call::ATTACH_CONTAINER_INPUT`. |
| */ |
| message ProcessIO { |
| enum Type { |
| UNKNOWN = 0; |
| DATA = 1; |
| CONTROL = 2; |
| } |
| |
| message Data { |
| enum Type { |
| UNKNOWN = 0; |
| STDIN = 1; |
| STDOUT = 2; |
| STDERR = 3; |
| } |
| |
| optional Type type = 1; |
| optional bytes data = 2; |
| } |
| |
| |
| message Control { |
| enum Type { |
| UNKNOWN = 0; |
| TTY_INFO = 1; |
| HEARTBEAT = 2; |
| } |
| |
| message Heartbeat { |
| optional DurationInfo interval = 1; |
| } |
| |
| optional Type type = 1; |
| optional TTYInfo tty_info = 2; |
| optional Heartbeat heartbeat = 3; |
| } |
| |
| optional Type type = 1; |
| optional Data data = 2; |
| optional Control control = 3; |
| } |