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}