use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize)]
pub struct SailboxHandle {
pub sailbox_id: String,
pub name: String,
pub status: String,
pub worker_address: String,
pub exec_endpoint: String,
}
#[derive(Debug, Clone, Serialize)]
pub struct SailboxInfo {
pub sailbox_id: String,
pub app_id: String,
pub app_name: String,
pub image_id: String,
pub name: String,
pub status: String,
pub memory_mib: i64,
pub vcpu_count: i64,
pub state_disk_size_gib: i64,
pub cpu_requested_vcpu: i64,
pub cpu_used_vcpu: f64,
pub memory_requested_bytes: i64,
pub memory_used_bytes: i64,
pub disk_requested_bytes: i64,
pub disk_used_bytes: i64,
pub architecture: String,
pub guest_schema_version: Option<i64>,
pub error_message: Option<String>,
pub checkpoint_generation: i64,
pub started_at: Option<String>,
pub last_checkpointed_at: Option<String>,
pub created_at: String,
pub updated_at: String,
}
#[derive(Deserialize)]
pub(crate) struct SailboxInfoWire {
sailbox_id: String,
app_id: String,
app_name: String,
#[serde(default)]
image_id: String,
name: String,
status: String,
memory_mib: i64,
vcpu_count: i64,
state_disk_size_gib: i64,
cpu_requested_vcpu: Option<i64>,
cpu_used_vcpu: Option<f64>,
memory_requested_bytes: Option<i64>,
memory_used_bytes: Option<i64>,
disk_requested_bytes: Option<i64>,
disk_used_bytes: Option<i64>,
architecture: String,
guest_schema_version: Option<i64>,
error_message: Option<String>,
checkpoint_generation: Option<i64>,
started_at: Option<String>,
last_checkpointed_at: Option<String>,
created_at: String,
updated_at: String,
}
impl From<SailboxInfoWire> for SailboxInfo {
fn from(w: SailboxInfoWire) -> SailboxInfo {
let memory_bytes = w.memory_mib.saturating_mul(1024 * 1024);
let disk_bytes = w.state_disk_size_gib.saturating_mul(1024 * 1024 * 1024);
SailboxInfo {
sailbox_id: w.sailbox_id,
app_id: w.app_id,
app_name: w.app_name,
image_id: w.image_id,
name: w.name,
status: w.status,
memory_mib: w.memory_mib,
vcpu_count: w.vcpu_count,
state_disk_size_gib: w.state_disk_size_gib,
cpu_requested_vcpu: w.cpu_requested_vcpu.unwrap_or(w.vcpu_count),
cpu_used_vcpu: w.cpu_used_vcpu.unwrap_or(0.0),
memory_requested_bytes: w.memory_requested_bytes.unwrap_or(memory_bytes),
memory_used_bytes: w.memory_used_bytes.unwrap_or(0),
disk_requested_bytes: w.disk_requested_bytes.unwrap_or(disk_bytes),
disk_used_bytes: w.disk_used_bytes.unwrap_or(0),
architecture: w.architecture,
guest_schema_version: w.guest_schema_version,
error_message: w.error_message,
checkpoint_generation: w.checkpoint_generation.unwrap_or(0),
started_at: w.started_at,
last_checkpointed_at: w.last_checkpointed_at,
created_at: w.created_at,
updated_at: w.updated_at,
}
}
}
#[derive(Debug, Clone, Serialize)]
pub struct SailboxPage {
pub items: Vec<SailboxInfo>,
pub limit: i64,
pub offset: i64,
pub total: i64,
pub has_more: bool,
}
#[derive(Debug, Clone, Serialize)]
pub struct SailboxCheckpoint {
pub checkpoint_id: String,
pub sailbox_id: String,
pub checkpoint_generation: i64,
pub status: String,
}
#[derive(Debug, Clone)]
pub struct ListQuery {
pub app: Option<String>,
pub status: Option<String>,
pub search: Option<String>,
pub max_guest_schema_version: Option<i64>,
pub limit: i64,
pub offset: i64,
}
pub const DEFAULT_LIST_LIMIT: i64 = 50;
pub const MAX_SAILBOX_VCPUS: i64 = 4;
pub const MIN_SAILBOX_MEMORY_MIB: i64 = 1024;
pub const MAX_SAILBOX_MEMORY_MIB: i64 = 8192;
pub const MAX_SAILBOX_DISK_GIB: i64 = 32;
impl Default for ListQuery {
fn default() -> ListQuery {
ListQuery {
app: None,
status: None,
search: None,
max_guest_schema_version: None,
limit: DEFAULT_LIST_LIMIT,
offset: 0,
}
}
}
#[derive(Debug, Clone, Serialize)]
pub struct IngressPort {
pub guest_port: u32,
pub protocol: String,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub allowlist: Vec<String>,
}
#[derive(Debug, Clone, Serialize)]
pub struct VolumeMount {
pub volume_id: String,
pub mount_path: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NfsVolume {
pub volume_id: String,
#[serde(default)]
pub name: String,
#[serde(default)]
pub backend: String,
#[serde(default)]
pub status: String,
#[serde(default)]
pub created_at: Option<String>,
#[serde(default)]
pub updated_at: Option<String>,
}
#[derive(Debug, Clone)]
pub struct CreateSailboxRequest {
pub app_id: String,
pub name: String,
pub ingress_ports: Vec<IngressPort>,
pub volume_mounts: Vec<VolumeMount>,
pub image: serde_json::Value,
pub cpu: Option<i64>,
pub memory_mib: Option<i64>,
pub state_disk_size_gib: Option<i64>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn list_query_default_uses_a_valid_nonzero_limit() {
let query = ListQuery::default();
assert_eq!(query.limit, DEFAULT_LIST_LIMIT);
assert!(query.limit > 0);
assert_eq!(query.offset, 0);
}
}