1// Copyright 2022 The ChromiumOS Authors 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5syntax = "proto3"; 6 7package chromiumos.test.api; 8 9import "chromiumos/test/api/cros_tool_runner_container_service_extensions.proto"; 10import "chromiumos/test/api/cros_tool_runner_container_service_templates.proto"; 11 12option go_package = "go.chromium.org/chromiumos/config/go/test/api"; 13 14// Exposes common docker commands as services 15service CrosToolRunnerContainerService { 16 // Creates a docker network 17 rpc CreateNetwork(CreateNetworkRequest) 18 returns (CreateNetworkResponse); 19 20 // Retrieves info of a docker network 21 rpc GetNetwork(GetNetworkRequest) 22 returns (GetNetworkResponse); 23 24 // Shuts down CTR container service 25 rpc Shutdown(ShutdownRequest) 26 returns (ShutdownResponse); 27 28 // Logs in a docker image registry server 29 // Call LoginRegistry before StartContainer to avoid permission denied errors. 30 // For login GCR, a client is required to run proper `gcloud auth` command to 31 // generate a token. For service account, the command is `gcloud auth 32 // activate-service-account`; for local development, the command is `gcloud 33 // auth login`. 34 // Note that the token is short lived for an hour. 35 rpc LoginRegistry(LoginRegistryRequest) 36 returns (LoginRegistryResponse); 37 38 // Runs a docker container with the provided start command. 39 // This assumes docker is already authenticated to pull the supplied image. 40 // The container will run in detached mode (-d); all exposed ports will be 41 // published to a random port on host (-P); and the container will be removed 42 // after it stops (--rm). 43 // StartContainer always returns a success response (for valid requests) as 44 // detached mode starts a container in the background. Clients may call 45 // GetContainer to verify the container has successfully started before use. 46 rpc StartContainer(StartContainerRequest) 47 returns (StartContainerResponse); 48 49 // Runs a docker container that has a template implemented. A template 50 // simplifies the data required in the request, and provides placeholders to 51 // populate information that is only known at runtime. E.g. dynamically mapped 52 // port number, IP address of a container. 53 // A template implementation converts the request to the generic 54 // StartContainer endpoint, and returns the generic StartContainerResponse. 55 rpc StartTemplatedContainer(StartTemplatedContainerRequest) 56 returns (StartContainerResponse); 57 58 // Executes a stack of commands in order. Only certain commands are supported. 59 rpc StackCommands(StackCommandsRequest) 60 returns (StackCommandsResponse); 61 62 // Retrieves information of a container 63 rpc GetContainer(GetContainerRequest) 64 returns (GetContainerResponse); 65} 66 67// Represents basic info of a docker network 68message Network { 69 // Network name 70 string name = 1; 71 // Network ID assigned by docker 72 string id = 2; 73 // Indicates if the network was created by the current container service. 74 bool owned = 3; 75} 76 77// Represents basic info of a docker container 78message Container { 79 // Container name 80 string name = 1; 81 // Container ID assigned by docker 82 string id = 2; 83 // Indicates if the container was started by the current container service. 84 bool owned = 3; 85 // A port binding is the mapping between the port used in the container and 86 // the port published on the host. Port bindings are defined through 87 // StartContainerRequest.options.expose and are retrieved through `docker 88 // container port` command. Example of the command output: 89 // `80/tcp -> 0.0.0.0:42356` 80 is the exposed port, 42356 is the published 90 // random port on the host 91 message PortBinding { 92 // The exposed port in the container, a.k.a the port a service listens to. 93 int32 container_port = 1; 94 // Always `tcp` for our use cases. 95 string protocol = 2; 96 // Host IP as returned by the command; we don't use this value. 97 string host_ip = 3; 98 // The published port on the host; each time `docker run` command assigns a 99 // random port available on the host is assigned. 100 int32 host_port = 4; 101 } 102 repeated PortBinding port_bindings = 4; 103} 104 105message CreateNetworkRequest { 106 string name = 1; 107} 108 109message CreateNetworkResponse { 110 Network network = 1; 111} 112 113message GetNetworkRequest { 114 string name = 1; 115} 116 117message GetNetworkResponse { 118 Network network = 1; 119} 120 121message ShutdownRequest {} 122message ShutdownResponse {} 123 124message LoginRegistryRequest { 125 // User name. For gcloud, this should be `oauth2accesstoken` 126 string username = 1; 127 // Password value or a command substitution. E.g. actual token value or 128 // $(gcloud auth print-access-token) 129 string password = 2; 130 // Registry server name. E.g. us-docker.pkg.dev 131 string registry = 3; 132 // Optional extensions to change behavior before the login action 133 LoginRegistryExtensions extensions = 4; 134} 135message LoginRegistryResponse { 136 // Message returned by docker login command 137 string message = 1; 138 // Messages returned by extensions 139 repeated string extensions_output = 2; 140} 141 142message StartContainerRequest { 143 // Unique name given to the container that will be used later to retrieve 144 // container info. 145 string name = 1; 146 // Location of image that can be directly pulled by docker. Note that start 147 // container assumes docker is already authenticated. 148 // e.g. us-docker.pkg.dev/cros-registry/test-services/cros-dut:latest 149 string container_image = 2; 150 // Supported options match corresponding `docker run` flags. 151 message Options { 152 // Expose port. see docker run --expose. All exposed ports will be published 153 // to a random port on the host. Currently only support one exposed port. 154 // e.g. 80 155 repeated string expose = 1; 156 // Volume mounting. see docker run --volume 157 // e.g. /tmp/host-src/cros-test:/tmp/container-dest/cros-test 158 repeated string volume = 2; 159 // Connect to the named docker network. see docker run --network 160 // e.g. bridge 161 string network = 3; 162 // Set environment variables. see docker run --env 163 // e.g. VAR1=123 164 repeated string env = 4; 165 } 166 // Additional options for `docker run`. 167 Options additional_options = 3; 168 // Command to run the server in a container. 169 // e.g. ["cros-dut", "-port", "80", ...] 170 repeated string start_command = 4; 171} 172 173message StartContainerResponse { 174 Container container = 1; 175} 176 177// StartTemplatedContainerRequest does not use additional_options or 178// start_command as in StartContainerRequest. Instead, container-specific 179// template is used to provide instructions on how to start the container. 180message StartTemplatedContainerRequest { 181 // Unique name given to the container that will be used later to retrieve 182 // container info. 183 string name = 1; 184 // Location of image that can be directly pulled by docker. Note that start 185 // container assumes docker is already authenticated. 186 // e.g. us-docker.pkg.dev/cros-registry/test-services/cros-dut:latest 187 string container_image = 2; 188 // Container-specific template 189 Template template = 3; 190 // Name of an existing network to join 191 string network = 4; 192 // Host directory to be mounted into the container for logs and other artifacts 193 string artifact_dir = 5; 194} 195 196message StackCommandsRequest { 197 message Stackable { 198 oneof command { 199 StartContainerRequest start_container = 1; 200 StartTemplatedContainerRequest start_templated_container = 2; 201 CreateNetworkRequest create_network = 3; 202 LoginRegistryRequest login_registry = 4; 203 } 204 } 205 repeated Stackable requests = 1; 206} 207 208message StackCommandsResponse { 209 message Stackable { 210 oneof output { 211 StartContainerResponse start_container = 1; 212 CreateNetworkResponse create_network = 2; 213 LoginRegistryResponse login_registry = 3; 214 } 215 } 216 repeated Stackable responses = 1; 217} 218 219message GetContainerRequest { 220 string name = 1; 221} 222 223message GetContainerResponse { 224 Container container = 1; 225} 226