// // Copyright 2017 HyperHQ Inc. // Copyright (c) 2019-2020 Ant Group // // SPDX-License-Identifier: Apache-2.0 // syntax = "proto3"; option go_package = "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols/grpc"; package grpc; import "oci.proto"; import "csi.proto"; import "types.proto"; import "google/protobuf/empty.proto"; // unstable service AgentService { // execution rpc CreateContainer(CreateContainerRequest) returns (google.protobuf.Empty); rpc StartContainer(StartContainerRequest) returns (google.protobuf.Empty); // RemoveContainer will tear down an existing container by forcibly terminating // all processes running inside that container and releasing all internal // resources associated with it. // RemoveContainer will wait for all processes termination before returning. // If any process can not be killed or if it can not be killed after // the RemoveContainerRequest timeout, RemoveContainer will return an error. rpc RemoveContainer(RemoveContainerRequest) returns (google.protobuf.Empty); rpc ExecProcess(ExecProcessRequest) returns (google.protobuf.Empty); rpc SignalProcess(SignalProcessRequest) returns (google.protobuf.Empty); rpc WaitProcess(WaitProcessRequest) returns (WaitProcessResponse); // wait & reap like waitpid(2) rpc UpdateContainer(UpdateContainerRequest) returns (google.protobuf.Empty); rpc StatsContainer(StatsContainerRequest) returns (StatsContainerResponse); rpc PauseContainer(PauseContainerRequest) returns (google.protobuf.Empty); rpc ResumeContainer(ResumeContainerRequest) returns (google.protobuf.Empty); // stdio rpc WriteStdin(WriteStreamRequest) returns (WriteStreamResponse); rpc ReadStdout(ReadStreamRequest) returns (ReadStreamResponse); rpc ReadStderr(ReadStreamRequest) returns (ReadStreamResponse); rpc CloseStdin(CloseStdinRequest) returns (google.protobuf.Empty); rpc TtyWinResize(TtyWinResizeRequest) returns (google.protobuf.Empty); // networking rpc UpdateInterface(UpdateInterfaceRequest) returns (types.Interface); rpc UpdateRoutes(UpdateRoutesRequest) returns (Routes); rpc ListInterfaces(ListInterfacesRequest) returns(Interfaces); rpc ListRoutes(ListRoutesRequest) returns (Routes); rpc AddARPNeighbors(AddARPNeighborsRequest) returns (google.protobuf.Empty); rpc GetIPTables(GetIPTablesRequest) returns (GetIPTablesResponse); rpc SetIPTables(SetIPTablesRequest) returns (SetIPTablesResponse); // observability rpc GetMetrics(GetMetricsRequest) returns (Metrics); // misc (TODO: some rpcs can be replaced by hyperstart-exec) rpc CreateSandbox(CreateSandboxRequest) returns (google.protobuf.Empty); rpc DestroySandbox(DestroySandboxRequest) returns (google.protobuf.Empty); rpc OnlineCPUMem(OnlineCPUMemRequest) returns (google.protobuf.Empty); rpc ReseedRandomDev(ReseedRandomDevRequest) returns (google.protobuf.Empty); rpc GetGuestDetails(GuestDetailsRequest) returns (GuestDetailsResponse); rpc MemHotplugByProbe(MemHotplugByProbeRequest) returns (google.protobuf.Empty); rpc SetGuestDateTime(SetGuestDateTimeRequest) returns (google.protobuf.Empty); rpc CopyFile(CopyFileRequest) returns (google.protobuf.Empty); rpc GetOOMEvent(GetOOMEventRequest) returns (OOMEvent); rpc AddSwap(AddSwapRequest) returns (google.protobuf.Empty); rpc GetVolumeStats(VolumeStatsRequest) returns (VolumeStatsResponse); rpc ResizeVolume(ResizeVolumeRequest) returns (google.protobuf.Empty); } message CreateContainerRequest { string container_id = 1; string exec_id = 2; StringUser string_user = 3; repeated Device devices = 4; repeated Storage storages = 5; Spec OCI = 6; // This field is used to indicate if the container needs to join // sandbox shared pid ns or create a new namespace. This field is // meant to override the NEWPID config settings in the OCI spec. // The agent would receive an OCI spec with PID namespace cleared // out altogether and not just the pid ns path. bool sandbox_pidns = 7; } message StartContainerRequest { string container_id = 1; } message RemoveContainerRequest { string container_id = 1; // RemoveContainer will return an error if // it could not kill some container processes // after timeout seconds. // Setting timeout to 0 means RemoveContainer will // wait for ever. uint32 timeout = 2; } message ExecProcessRequest { string container_id = 1; string exec_id = 2; StringUser string_user = 3; Process process = 4; } message SignalProcessRequest { string container_id = 1; // Special case for SignalProcess(): exec_id can be empty(""), // which means to send the signal to all the processes including their descendants. // Other APIs with exec_id should treat empty exec_id as an invalid request. string exec_id = 2; uint32 signal = 3; } message WaitProcessRequest { string container_id = 1; string exec_id = 2; } message WaitProcessResponse { int32 status = 1; } message UpdateContainerRequest { string container_id = 1; LinuxResources resources = 2; } message StatsContainerRequest { string container_id = 1; } message PauseContainerRequest { string container_id = 1; } message ResumeContainerRequest { string container_id = 1; } message CpuUsage { uint64 total_usage = 1; repeated uint64 percpu_usage = 2; uint64 usage_in_kernelmode = 3; uint64 usage_in_usermode = 4; } message ThrottlingData { uint64 periods = 1; uint64 throttled_periods = 2; uint64 throttled_time = 3; } message CpuStats { CpuUsage cpu_usage = 1; ThrottlingData throttling_data = 2; } message PidsStats { uint64 current = 1; uint64 limit = 2; } message MemoryData { uint64 usage = 1; uint64 max_usage = 2; uint64 failcnt = 3; uint64 limit = 4; } message MemoryStats { uint64 cache = 1; MemoryData usage = 2; MemoryData swap_usage = 3; MemoryData kernel_usage = 4; bool use_hierarchy = 5; map stats = 6; } message BlkioStatsEntry { uint64 major = 1; uint64 minor = 2; string op = 3; uint64 value = 4; } message BlkioStats { repeated BlkioStatsEntry io_service_bytes_recursive = 1; // number of bytes transferred to and from the block device repeated BlkioStatsEntry io_serviced_recursive = 2; repeated BlkioStatsEntry io_queued_recursive = 3; repeated BlkioStatsEntry io_service_time_recursive = 4; repeated BlkioStatsEntry io_wait_time_recursive = 5; repeated BlkioStatsEntry io_merged_recursive = 6; repeated BlkioStatsEntry io_time_recursive = 7; repeated BlkioStatsEntry sectors_recursive = 8; } message HugetlbStats { uint64 usage = 1; uint64 max_usage = 2; uint64 failcnt = 3; } message CgroupStats { CpuStats cpu_stats = 1; MemoryStats memory_stats = 2; PidsStats pids_stats = 3; BlkioStats blkio_stats = 4; map hugetlb_stats = 5; // the map is in the format "size of hugepage: stats of the hugepage" } message NetworkStats { string name = 1; uint64 rx_bytes = 2; uint64 rx_packets = 3; uint64 rx_errors = 4; uint64 rx_dropped = 5; uint64 tx_bytes = 6; uint64 tx_packets = 7; uint64 tx_errors = 8; uint64 tx_dropped = 9; } message StatsContainerResponse { CgroupStats cgroup_stats = 1; repeated NetworkStats network_stats = 2; } message WriteStreamRequest { string container_id = 1; string exec_id = 2; bytes data = 3; } message WriteStreamResponse { uint32 len = 1; } message ReadStreamRequest { string container_id = 1; string exec_id = 2; uint32 len = 3; } message ReadStreamResponse { bytes data = 1; } message CloseStdinRequest { string container_id = 1; string exec_id = 2; } message TtyWinResizeRequest { string container_id = 1; string exec_id = 2; uint32 row = 3; uint32 column = 4; } message KernelModule { // This field is the name of the kernel module. string name = 1; // This field are the parameters for the kernel module which are // whitespace-delimited key=value pairs passed to modprobe(8). repeated string parameters = 2; } message CreateSandboxRequest { string hostname = 1; repeated string dns = 2; repeated Storage storages = 3; // This field means that a pause process needs to be created by the // agent. This pid namespace of the pause process will be treated as // a shared pid namespace. All containers created will join this shared // pid namespace. bool sandbox_pidns = 4; // SandboxId identifies which sandbox is using the agent. We allow only // one sandbox per agent and implicitly require that CreateSandbox is // called before other sandbox/network calls. string sandbox_id = 5; // This field, if non-empty, designates an absolute path to a directory // that the agent will search for OCI hooks to run within the guest. string guest_hook_path = 6; // This field is the list of kernel modules to be loaded in the guest kernel. repeated KernelModule kernel_modules = 7; } message DestroySandboxRequest { } message Interfaces { repeated types.Interface Interfaces = 1; } message Routes { repeated types.Route Routes = 1; } message UpdateInterfaceRequest { types.Interface interface = 1; } message UpdateRoutesRequest { Routes routes = 1; } message ListInterfacesRequest { } message ListRoutesRequest { } message ARPNeighbors { repeated types.ARPNeighbor ARPNeighbors = 1; } message AddARPNeighborsRequest { ARPNeighbors neighbors = 1; } message GetIPTablesRequest { bool is_ipv6 = 1; } message GetIPTablesResponse{ // raw stdout from iptables-save or ip6tables-save bytes data = 1; } message SetIPTablesRequest { bool is_ipv6 = 1; // iptables, in raw format expected to be passed to stdin // of iptables-save or ip6tables-save bytes data = 2; } message SetIPTablesResponse{ // raw stdout from iptables-restore or ip6tables-restore bytes data = 1; } message OnlineCPUMemRequest { // Wait specifies if the caller waits for the agent to online all resources. // If true the agent returns once all resources have been connected, otherwise all // resources are connected asynchronously and the agent returns immediately. bool wait = 1; // NbCpus specifies the number of CPUs that were added and the agent has to online. uint32 nb_cpus = 2; // CpuOnly specifies whether only online CPU or not. bool cpu_only = 3; } message ReseedRandomDevRequest { // Data specifies the random data used to reseed the guest crng. bytes data = 2; } // AgentDetails provides information to the client about the running agent. message AgentDetails { // Semantic version of agent (see https://semver.org). string version = 1; // Set if the agent is running as PID 1. bool init_daemon = 2; // List of available device handlers. repeated string device_handlers = 3; // List of available storage handlers. repeated string storage_handlers = 4; // Set only if the agent is built with seccomp support and the guest // environment supports seccomp. bool supports_seccomp = 5; } message GuestDetailsRequest { // MemBlockSize asks server to return the system memory block size that can be used // for memory hotplug alignment. Typically the server returns what's in // /sys/devices/system/memory/block_size_bytes. bool mem_block_size = 1; // MemoryHotplugProbe asks server to return whether guest kernel supports memory hotplug // via probeinterface. Typically the server will check if the path // /sys/devices/system/memory/probe exists. bool mem_hotplug_probe = 2; } message GuestDetailsResponse { // MemBlockSizeBytes returns the system memory block size in bytes. uint64 mem_block_size_bytes = 1; AgentDetails agent_details = 2; bool support_mem_hotplug_probe = 3; } message MemHotplugByProbeRequest { // server needs to send the value of memHotplugProbeAddr into file /sys/devices/system/memory/probe, // in order to notify the guest kernel about hot-add memory event repeated uint64 memHotplugProbeAddr = 1; } message SetGuestDateTimeRequest { // Sec the second since the Epoch. int64 Sec = 1; // Usec the microseconds portion of time since the Epoch. int64 Usec = 2; } // FSGroup consists of the group id and group ownership change policy // that a volume should have its ownership changed to. message FSGroup { // GroupID is the ID that the group ownership of the // files in the mounted volume will need to be changed to. uint32 group_id = 2; // GroupChangePolicy specifies the policy for applying group id // ownership change on a mounted volume. types.FSGroupChangePolicy group_change_policy = 3; } // Storage represents both the rootfs of the container, and any volume that // could have been defined through the Mount list of the OCI specification. message Storage { // Driver is used to define the way the storage is passed through the // virtual machine. It can be "9p", "blk", or something else, but for // all cases, this will define if some extra steps are required before // this storage gets mounted into the container. string driver = 1; // DriverOptions allows the caller to define a list of options such // as block sizes, numbers of luns, ... which are very specific to // every device and cannot be generalized through extra fields. repeated string driver_options = 2; // Source can be anything representing the source of the storage. This // will be handled by the proper handler based on the Driver used. // For instance, it can be a very simple path if the caller knows the // name of device inside the VM, or it can be some sort of identifier // to let the agent find the device inside the VM. string source = 3; // Fstype represents the filesystem that needs to be used to mount the // storage inside the VM. For instance, it could be "xfs" for block // device, "9p" for shared filesystem, or "tmpfs" for shared /dev/shm. string fstype = 4; // Options describes the additional options that might be needed to // mount properly the storage filesystem. repeated string options = 5; // MountPoint refers to the path where the storage should be mounted // inside the VM. string mount_point = 6; // FSGroup consists of the group ID and group ownership change policy // that the mounted volume must have its group ID changed to when specified. FSGroup fs_group = 7; } // Device represents only the devices that could have been defined through the // Linux Device list of the OCI specification. message Device { // Id can be used to identify the device inside the VM. Some devices // might not need it to be identified on the VM, and will rely on the // provided VmPath instead. string id = 1; // Type defines the type of device described. This can be "blk", // "scsi", "vfio", ... // Particularly, this should be used to trigger the use of the // appropriate device handler. string type = 2; // VmPath can be used by the caller to provide directly the path of // the device as it will appear inside the VM. For some devices, the // device id or the list of options passed might not be enough to find // the device. In those cases, the caller should predict and provide // this vm_path. string vm_path = 3; // ContainerPath defines the path where the device should be found inside // the container. This path should match the path of the device from // the device list listed inside the OCI spec. This is used in order // to identify the right device in the spec and update it with the // right options such as major/minor numbers as they appear inside // the VM for instance. Note that an empty ctr_path should be used // to make sure the device handler inside the agent is called, but // no spec update needs to be performed. This has to happen for the // case of rootfs, when a device has to be waited for after it has // been hotplugged. An equivalent Storage entry should be defined if // any mount needs to be performed afterwards. string container_path = 4; // Options allows the caller to define a list of options such as block // sizes, numbers of luns, ... which are very specific to every device // and cannot be generalized through extra fields. repeated string options = 5; } message StringUser { string uid = 1; string gid = 2; repeated string additionalGids = 3; } message CopyFileRequest { // Path is the destination file in the guest. It must be absolute, // canonical and below /run. string path = 1; // FileSize is the expected file size, for security reasons write operations // are made in a temporary file, once it has the expected size, it's moved // to the destination path. int64 file_size = 2; // FileMode is the file mode. uint32 file_mode = 3; // DirMode is the mode for the parent directories of destination path. uint32 dir_mode = 4; // Uid is the numeric user id. int32 uid = 5; // Gid is the numeric group id. int32 gid = 6; // Offset for the next write operation. int64 offset = 7; // Data to write in the destination file. bytes data = 8; } message GetOOMEventRequest {} message OOMEvent { string container_id = 1; } message AddSwapRequest { repeated uint32 PCIPath = 1; } message GetMetricsRequest {} message Metrics { string metrics = 1; } message VolumeStatsRequest { // The volume path on the guest outside the container string volume_guest_path = 1; } message ResizeVolumeRequest { // Full VM guest path of the volume (outside the container) string volume_guest_path = 1; uint64 size = 2; }