microsandbox_server/payload.rs
1//! Request and response payload definitions for the microsandbox server.
2//!
3//! This module defines the data structures for:
4//! - API request payloads for sandbox operations
5//! - API response payloads for operation results
6//! - Error response structures and types
7//! - Status message formatting
8//!
9//! The module implements:
10//! - Request/response serialization and deserialization
11//! - Structured error responses with type categorization
12//! - Success message formatting for sandbox operations
13//! - Detailed error information handling
14
15use serde::{Deserialize, Serialize};
16use serde_json::Value;
17
18//--------------------------------------------------------------------------------------------------
19// Constants
20//--------------------------------------------------------------------------------------------------
21
22/// JSON-RPC version - always "2.0"
23pub const JSONRPC_VERSION: &str = "2.0";
24
25//--------------------------------------------------------------------------------------------------
26// Types: JSON-RPC Payloads
27//--------------------------------------------------------------------------------------------------
28
29/// JSON-RPC request structure
30#[derive(Debug, Deserialize, Serialize)]
31pub struct JsonRpcRequest {
32 /// JSON-RPC version, must be "2.0"
33 pub jsonrpc: String,
34
35 /// Method name
36 pub method: String,
37
38 /// Optional parameters for the method
39 #[serde(default)]
40 pub params: Value,
41
42 /// Request ID
43 pub id: Value,
44}
45
46/// JSON-RPC response structure
47#[derive(Debug, Deserialize, Serialize)]
48pub struct JsonRpcResponse {
49 /// JSON-RPC version, always "2.0"
50 pub jsonrpc: String,
51
52 /// Result of the method execution (if successful)
53 #[serde(skip_serializing_if = "Option::is_none")]
54 pub result: Option<Value>,
55
56 /// Error details (if failed)
57 #[serde(skip_serializing_if = "Option::is_none")]
58 pub error: Option<JsonRpcError>,
59
60 /// Response ID (same as request ID)
61 pub id: Value,
62}
63
64/// JSON-RPC error structure
65#[derive(Debug, Deserialize, Serialize)]
66pub struct JsonRpcError {
67 /// Error code
68 pub code: i32,
69
70 /// Error message
71 pub message: String,
72
73 /// Optional error data
74 #[serde(skip_serializing_if = "Option::is_none")]
75 pub data: Option<Value>,
76}
77
78//--------------------------------------------------------------------------------------------------
79// Types: Server Operations
80//--------------------------------------------------------------------------------------------------
81
82/// Request payload for starting a sandbox
83#[derive(Debug, Deserialize)]
84pub struct SandboxStartParams {
85 /// Sandbox name
86 pub sandbox: String,
87
88 /// Optional namespace
89 pub namespace: String,
90
91 /// Optional sandbox configuration
92 pub config: Option<SandboxConfig>,
93}
94
95/// Request payload for stopping a sandbox
96#[derive(Debug, Deserialize)]
97pub struct SandboxStopParams {
98 /// Sandbox name
99 pub sandbox: String,
100
101 /// Optional namespace
102 pub namespace: String,
103}
104
105/// Request payload for getting sandbox status
106#[derive(Debug, Deserialize)]
107pub struct SandboxStatusParams {
108 /// Optional sandbox name - if not provided, all sandboxes in the namespace will be included
109 pub sandbox: Option<String>,
110
111 /// Namespace - use "*" to get status from all namespaces
112 pub namespace: String,
113}
114
115/// Configuration for a sandbox
116/// Similar to microsandbox-core's Sandbox but with optional fields for update operations
117#[derive(Debug, Deserialize)]
118pub struct SandboxConfig {
119 /// The image to use (optional for updates)
120 pub image: Option<String>,
121
122 /// The amount of memory in MiB to use
123 pub memory: Option<u32>,
124
125 /// The number of vCPUs to use
126 pub cpus: Option<u8>,
127
128 /// The volumes to mount
129 #[serde(default)]
130 pub volumes: Vec<String>,
131
132 /// The ports to expose
133 #[serde(default)]
134 pub ports: Vec<String>,
135
136 /// The environment variables to use
137 #[serde(default)]
138 pub envs: Vec<String>,
139
140 /// The sandboxes to depend on
141 #[serde(default)]
142 pub depends_on: Vec<String>,
143
144 /// The working directory to use
145 pub workdir: Option<String>,
146
147 /// The shell to use (optional for updates)
148 pub shell: Option<String>,
149
150 /// The scripts that can be run
151 #[serde(default)]
152 pub scripts: std::collections::HashMap<String, String>,
153
154 /// The exec command to run
155 pub exec: Option<String>,
156 // SECURITY: Needs networking namespacing to be implemented
157 // /// The network scope for the sandbox
158 // pub scope: Option<String>,
159}
160
161//--------------------------------------------------------------------------------------------------
162// Types: Portal-mirrored RPC Payloads
163//--------------------------------------------------------------------------------------------------
164
165/// Request parameters for executing code in a REPL environment
166#[derive(Debug, Deserialize, Serialize)]
167pub struct SandboxReplRunParams {
168 /// Code to be executed
169 pub code: String,
170
171 /// Programming language to use for execution
172 pub language: String,
173}
174
175/// Request parameters for retrieving output from a previous REPL execution
176#[derive(Debug, Deserialize, Serialize)]
177pub struct SandboxReplGetOutputParams {
178 /// Unique identifier for the execution
179 pub execution_id: String,
180}
181
182/// Request parameters for executing a shell command
183#[derive(Debug, Deserialize, Serialize)]
184pub struct SandboxCommandExecuteParams {
185 /// Command to execute
186 pub command: String,
187
188 /// Optional arguments for the command
189 #[serde(default)]
190 pub args: Vec<String>,
191}
192
193/// Request parameters for retrieving output from a previous command execution
194#[derive(Debug, Deserialize, Serialize)]
195pub struct SandboxCommandGetOutputParams {
196 /// Unique identifier for the command execution
197 pub execution_id: String,
198}
199
200//--------------------------------------------------------------------------------------------------
201// Methods
202//--------------------------------------------------------------------------------------------------
203
204impl JsonRpcRequest {
205 /// Create a new JSON-RPC request
206 pub fn new(method: String, params: Value, id: Value) -> Self {
207 Self {
208 jsonrpc: JSONRPC_VERSION.to_string(),
209 method,
210 params,
211 id,
212 }
213 }
214}
215
216impl JsonRpcResponse {
217 /// Create a new successful JSON-RPC response
218 pub fn success(result: Value, id: Value) -> Self {
219 Self {
220 jsonrpc: JSONRPC_VERSION.to_string(),
221 result: Some(result),
222 error: None,
223 id,
224 }
225 }
226
227 /// Create a new error JSON-RPC response
228 pub fn error(error: JsonRpcError, id: Value) -> Self {
229 Self {
230 jsonrpc: JSONRPC_VERSION.to_string(),
231 result: None,
232 error: Some(error),
233 id,
234 }
235 }
236}
237
238//--------------------------------------------------------------------------------------------------
239// Types: Responses
240//--------------------------------------------------------------------------------------------------
241
242/// Response type for regular message responses
243#[derive(Debug, Serialize)]
244pub struct RegularMessageResponse {
245 /// Message indicating the status of the sandbox operation
246 pub message: String,
247}
248
249/// System status response
250#[derive(Debug, Serialize)]
251pub struct SystemStatusResponse {}
252
253/// Sandbox status response
254#[derive(Debug, Serialize)]
255pub struct SandboxStatusResponse {
256 /// List of sandbox statuses
257 pub sandboxes: Vec<SandboxStatus>,
258}
259
260/// Sandbox configuration response
261#[derive(Debug, Serialize)]
262pub struct SandboxConfigResponse {}
263
264/// Status of an individual sandbox
265#[derive(Debug, Serialize)]
266pub struct SandboxStatus {
267 /// Namespace the sandbox belongs to
268 pub namespace: String,
269
270 /// The name of the sandbox
271 pub name: String,
272
273 /// Whether the sandbox is running
274 pub running: bool,
275
276 /// CPU usage percentage
277 pub cpu_usage: Option<f32>,
278
279 /// Memory usage in MiB
280 pub memory_usage: Option<u64>,
281
282 /// Disk usage of the RW layer in bytes
283 pub disk_usage: Option<u64>,
284}