// Copyright 2023 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. syntax = "proto3"; package chromiumos.test.api; option go_package = "go.chromium.org/chromiumos/config/go/test/api"; import "google/protobuf/duration.proto"; import "google/protobuf/timestamp.proto"; import "chromiumos/test/api/device_leasing.proto"; service DeviceLeaseService { // Lease a device and create a lease. rpc LeaseDevice(LeaseDeviceRequest) returns (LeaseDeviceResponse) {}; // Bulk lease devices and create leases for all of them. rpc BulkLeaseDevices(BulkLeaseDevicesRequest) returns (BulkLeaseDevicesResponse) {}; // Release a device lease. rpc ReleaseDevice(ReleaseDeviceRequest) returns (ReleaseDeviceResponse) {}; // Extend a device lease by modifying the expiration time. rpc ExtendLease(ExtendLeaseRequest) returns (ExtendLeaseResponse) {}; // Get a device by device id. // Designed to adhere to https://google.aip.dev/131. rpc GetDevice(GetDeviceRequest) returns (Device) {}; // List devices managed by Device Manager. // Designed to adhere to https://google.aip.dev/132. rpc ListDevices(ListDevicesRequest) returns (ListDevicesResponse) {}; } message Device { // In the case of VMs, device id could be the GCE instance name. For physical // DUTs we use the IDs we get from UFS. string id = 1; // dut_id is the asset tag for a Device string dut_id = 6; DeviceAddress address = 2; DeviceType type = 3; DeviceState state = 4; // This proto contains per-DUT hardware relevant information including labels. HardwareRequirements hardware_reqs = 5; } message DeviceAddress { // IP address of the device. // For physical DUTs it can be a hostname. string host = 1; int32 port = 2; } // This is different than device features which are expressed in // requirements_eq. This is more about virtual, physical, or either initially. enum DeviceType { DEVICE_TYPE_UNSPECIFIED = 0; DEVICE_TYPE_VIRTUAL = 1; DEVICE_TYPE_PHYSICAL = 2; } // The list is not final and can be extended later. enum DeviceState { DEVICE_STATE_UNSPECIFIED = 0; // Default state. // Device is available to be leased. DEVICE_STATE_AVAILABLE = 1; // Device is leased. DEVICE_STATE_LEASED = 2; } message DeviceLeaseRecord { // Lease id // Should be uniquely generated by UUID4. string id = 1; // Key specified by client per request. // Requests with the same key will be treated as duplicate requests. string idempotency_key = 2; // Device data. // Id (hostname) corresponding to the device name. string device_id = 3; // DUT ID (asset tag) corresponding to the device name. string dut_id = 11; // SSH-able address to access the device. DeviceAddress device_address = 4; // Type of device leased. DeviceType device_type = 5; // Tracking times. // Time when the device was leased. google.protobuf.Timestamp leased_time = 6; // Time when the device was released by a request or cron. google.protobuf.Timestamp released_time = 7; // Lease expiration time. The time can be updated several times. // The record keeps the last known value. google.protobuf.Timestamp expiration_time = 8; // Last updated time. The time when the lease was last updated. // This will be used as a versioning timestamp google.protobuf.Timestamp last_updated_time = 9; // Request data. // All parameters used to create a device will be saved for further analysis. // Possible that the data will be removed later if established as not needed. map request_parameters = 10; } message LeaseDeviceRequest { // Generated on the client side, shared across retries but pseudo-unique // across different logical requests. Requests with the same key will be // treated as duplicate of original request, return the same response. string idempotency_key = 1; // This is the final end user (can be human or robot). Useful for both // debugging and analytics. For example, for a tests triggered for a CL, // this field could indicate the CL author as they are the end user. // // For direct invocations like CLI, this is enforced at first entry point // but trusted from there. // // Not to be confused with LUCI auth which is done by the caller assuming // the appropriate identity from a permissions perspective — like LUCI // project. string on_behalf_of = 2; // This is the quota the end user is requesting to use. One user can have // access to multiple quotas. For example, release, CQ, performance testing, // etc. string quota_id = 3; // Optional with a good default. // Important to configure a good max (e.g. 10 min). This will put a ceiling // on time wasted if the client dies. google.protobuf.Duration lease_duration = 4; // The populated requirements will specify what kind of device manager // returns. The client can populate both to indicate that they are ok with // either a VM or Hardware DUT. VMRequirements vm_host_reqs = 5; HardwareRequirements hardware_device_reqs = 6; } message LeaseDeviceResponse { DeviceLeaseRecord device_lease = 1; // Eventually we will include authentication token to access device for the // duration of the lease. Shared and long lived secrets are not good security. // Today there is no such enforcement so this is not a regression. LeaseDeviceResponseErrorType error_type = 2; string error_string = 3; } enum LeaseDeviceResponseErrorType { LEASE_ERROR_TYPE_NONE = 0; LEASE_ERROR_TYPE_DEVICE_NOT_FOUND = 1; LEASE_ERROR_TYPE_DEVICE_ALREADY_LEASED = 2; } message BulkLeaseDevicesRequest { // A list of LeaseDeviceRequests. repeated LeaseDeviceRequest lease_device_requests = 1; } message BulkLeaseDevicesResponse { // One LeaseDeviceResponse for each LeaseDeviceRequest in the // BulkLeaseDevicesRequest. repeated LeaseDeviceResponse lease_device_responses = 1; // Overall error for the bulk request. It is possible for the response to // error with partial success of leasing. BulkLeaseDevicesResponseErrorType error_type = 2; string error_string = 3; } enum BulkLeaseDevicesResponseErrorType { BULK_LEASE_ERROR_TYPE_NONE = 0; // Internal Postgres errors. BULK_LEASE_ERROR_TYPE_INTERNAL_DATABASE_ERR = 1; // Some Devices failed to be leased. See individual lease request errors. BULK_LEASE_ERROR_TYPE_PARTIAL_LEASE_FAILURE = 2; } message ReleaseDeviceRequest { string lease_id = 1; } message ReleaseDeviceResponse { string lease_id = 1; ReleaseDeviceResponseErrorType error_type = 2; string error_string = 3; } enum ReleaseDeviceResponseErrorType { ERROR_TYPE_NONE = 0; ERROR_TYPE_DEVICE_ALREADY_RELEASED = 1; } message GetDeviceRequest { // The name of the device to retrieve. // Format: devices/{device_id}. string name = 1; } // The response for GetDevice is Device. message ListDevicesRequest { // The parent for which to list devices. Based on collections of pools. // If no parent is specified, all devices will be queried. // Format: pools/{pool}. string parent = 1; // The maximum number of devices to return. The service may return fewer than // this value. If unspecified, at most 50 devices will be returned. int32 page_size = 2; // A page token, received from a previous `ListDevices` call. Provide this to // retrieve the subsequent page. // // When paginating, all other parameters provided to `ListDevices` must match // the call that provided the page token. string page_token = 3; // The string filter follows AIP-160 (https://google.aip.dev/160) for the // filtering syntax. string filter = 4; } message ListDevicesResponse { // List of devices to be returned. repeated Device devices = 1; // A token, which can be sent as `page_token` to retrieve the next page. If // this field is omitted, there are no subsequent pages. string next_page_token = 2; }