Skip to content

Commit 3500a6f

Browse files
committed
Introduce proto files for Task API and Container Service
Signed-off-by: Guvenc Gulce <[email protected]>
1 parent 9a5173b commit 3500a6f

File tree

3 files changed

+240
-1
lines changed

3 files changed

+240
-1
lines changed

feos/proto/build.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
1111
format!("{proto_dir}/vm.proto"),
1212
format!("{proto_dir}/host.proto"),
1313
format!("{proto_dir}/image.proto"),
14+
format!("{proto_dir}/container.proto"),
15+
format!("{proto_dir}/task.proto"),
1416
],
1517
&[proto_dir],
1618
)?;
1719
Ok(())
18-
}
20+
}

proto/v1/container.proto

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
syntax = "proto3";
2+
3+
package feos.container.v1;
4+
5+
import "google/protobuf/any.proto";
6+
7+
// ContainerService manages the lifecycle of containers. It provides an
8+
// external-facing API for clients to create, run, and manage containers,
9+
// abstracting the underlying details of shims and runtimes like youki.
10+
service ContainerService {
11+
// Creates a new container from an OCI image but does not start it.
12+
// This call is asynchronous. It will first trigger an image pull if the
13+
// image is not available locally. The service returns a container_id immediately.
14+
// Clients can then use StreamContainerEvents to track the progress from
15+
// "PULLING_IMAGE" to "CREATED".
16+
rpc CreateContainer(CreateContainerRequest) returns (CreateContainerResponse);
17+
18+
// Starts a previously created container.
19+
rpc StartContainer(StartContainerRequest) returns (StartContainerResponse);
20+
21+
// Stops a running container by sending it a configurable signal.
22+
rpc StopContainer(StopContainerRequest) returns (StopContainerResponse);
23+
24+
// Retrieves detailed information about a specific container.
25+
rpc GetContainer(GetContainerRequest) returns (ContainerInfo);
26+
27+
// Lists all containers currently managed by the service.
28+
rpc ListContainers(ListContainersRequest) returns (ListContainersResponse);
29+
30+
// Deletes a container, cleaning up all associated resources including its
31+
// root filesystem. The container must be in a stopped state.
32+
rpc DeleteContainer(DeleteContainerRequest) returns (DeleteContainerResponse);
33+
34+
// Streams logs (stdout and stderr) from a running or stopped container.
35+
rpc StreamContainerLogs(StreamContainerLogsRequest) returns (stream LogEntry);
36+
37+
// Streams lifecycle events for one or all containers. This is useful for
38+
// tracking the status of asynchronous operations like CreateContainer.
39+
rpc StreamContainerEvents(StreamContainerEventsRequest) returns (stream ContainerEvent);
40+
}
41+
42+
// Configuration for creating a new container.
43+
message ContainerConfig {
44+
// Reference to the OCI image to use for the container's root filesystem
45+
// (e.g., "docker.io/library/alpine:latest").
46+
string image_ref = 1;
47+
// Optional command to execute inside the container. If not provided, the
48+
// image's default command (from its config) is used.
49+
repeated string command = 2;
50+
// Optional environment variables to set inside the container.
51+
map<string, string> env = 3;
52+
}
53+
54+
message CreateContainerRequest {
55+
// The configuration for the container.
56+
ContainerConfig config = 1;
57+
// An optional client-provided ID for the container. If not provided, a
58+
// UUID will be generated.
59+
optional string container_id = 2;
60+
}
61+
62+
message CreateContainerResponse {
63+
// The unique ID of the newly created container.
64+
string container_id = 1;
65+
}
66+
67+
message StartContainerRequest {
68+
string container_id = 1;
69+
}
70+
71+
message StartContainerResponse {}
72+
73+
message StopContainerRequest {
74+
string container_id = 1;
75+
// Optional signal to send for stopping the container. Defaults to SIGTERM.
76+
optional uint32 signal = 2;
77+
// Optional timeout in seconds to wait before sending SIGKILL if the container
78+
// has not stopped.
79+
optional uint32 timeout_seconds = 3;
80+
}
81+
82+
message StopContainerResponse {}
83+
84+
message GetContainerRequest {
85+
string container_id = 1;
86+
}
87+
88+
message ListContainersRequest {}
89+
90+
message ListContainersResponse {
91+
repeated ContainerInfo containers = 1;
92+
}
93+
94+
message DeleteContainerRequest {
95+
string container_id = 1;
96+
}
97+
98+
message DeleteContainerResponse {}
99+
100+
message StreamContainerLogsRequest {
101+
string container_id = 1;
102+
// If true, the stream will not close when the end of the log is reached,
103+
// but will wait for new log entries.
104+
bool follow = 2;
105+
// If true, sends all previous logs before streaming new ones.
106+
bool tail = 3;
107+
}
108+
109+
message LogEntry {
110+
// The raw log line from either stdout or stderr.
111+
bytes line = 1;
112+
// Specifies the source stream of the log line.
113+
enum Source {
114+
SOURCE_UNSPECIFIED = 0;
115+
STDOUT = 1;
116+
STDERR = 2;
117+
}
118+
Source source = 2;
119+
}
120+
121+
enum ContainerState {
122+
CONTAINER_STATE_UNSPECIFIED = 0;
123+
// The service is pulling the OCI image for the container.
124+
PULLING_IMAGE = 1;
125+
// The container's resources have been prepared, and it is ready to be started.
126+
CREATED = 2;
127+
// The container is currently running.
128+
RUNNING = 3;
129+
// The container process has exited.
130+
STOPPED = 4;
131+
}
132+
133+
// Represents information about a single container.
134+
message ContainerInfo {
135+
string container_id = 1;
136+
ContainerState state = 2;
137+
ContainerConfig config = 3;
138+
// The process ID of the container, if it is running.
139+
optional int64 pid = 4;
140+
// The exit code of the container process, if it has stopped.
141+
optional int32 exit_code = 5;
142+
}
143+
144+
// --- Event Streaming Messages ---
145+
146+
message StreamContainerEventsRequest {
147+
// The ID of the container for which to retrieve events.
148+
// If not provided, the stream will send events for all containers.
149+
optional string container_id = 1;
150+
}
151+
152+
message ContainerEvent {
153+
string container_id = 1;
154+
// A unique identifier for the event.
155+
string id = 2;
156+
// The specific event payload.
157+
google.protobuf.Any data = 3;
158+
}
159+
160+
message ContainerStateChangedEvent {
161+
ContainerState new_state = 1;
162+
// A human-readable reason for the state change.
163+
string reason = 2;
164+
}

proto/v1/task.proto

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
syntax = "proto3";
2+
3+
package feos.task.v1;
4+
5+
// TaskService is an internal-only API implemented by the `feos --shim` process.
6+
// It provides a low-level interface for the container-service to manage the
7+
// lifecycle of a single container using an OCI runtime like `youki`.
8+
service TaskService {
9+
// Creates the container's environment based on an OCI bundle but does not
10+
// start the user-specified process.
11+
rpc Create(CreateRequest) returns (CreateResponse);
12+
13+
// Starts the user-specified process within the created container.
14+
rpc Start(StartRequest) returns (StartResponse);
15+
16+
// Sends a signal to the container's process.
17+
rpc Kill(KillRequest) returns (KillResponse);
18+
19+
// Deletes the container and cleans up its resources. The container must be
20+
// stopped.
21+
rpc Delete(DeleteRequest) returns (DeleteResponse);
22+
23+
// Waits for the container's process to exit and returns its exit status.
24+
// This is a long-polling RPC that will only return once the process has
25+
// terminated.
26+
rpc Wait(WaitRequest) returns (WaitResponse);
27+
}
28+
29+
message CreateRequest {
30+
string container_id = 1;
31+
// Absolute path to the OCI bundle directory, which contains the 'config.json'
32+
// and the 'rootfs' subdirectory.
33+
string bundle_path = 2;
34+
// Path to a socket or file for the container's stdin.
35+
string stdin_path = 3;
36+
// Path to a socket or file for the container's stdout.
37+
string stdout_path = 4;
38+
// Path to a socket or file for the container's stderr.
39+
string stderr_path = 5;
40+
}
41+
42+
message CreateResponse {
43+
// The process ID of the created container's init process.
44+
int64 pid = 1;
45+
}
46+
47+
message StartRequest {
48+
string container_id = 1;
49+
}
50+
51+
message StartResponse {}
52+
53+
message KillRequest {
54+
string container_id = 1;
55+
// The signal number to send to the process.
56+
uint32 signal = 2;
57+
}
58+
59+
message KillResponse {}
60+
61+
message DeleteRequest {
62+
string container_id = 1;
63+
}
64+
65+
message DeleteResponse {}
66+
67+
message WaitRequest {
68+
string container_id = 1;
69+
}
70+
71+
message WaitResponse {
72+
int32 exit_code = 1;
73+
}

0 commit comments

Comments
 (0)