use serde::{Deserialize, Serialize};
use std::path::PathBuf;
pub type DiskCompactionResult = microsandbox_types::DiskCompactionResult;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct Empty {}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct Capabilities {
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub root_disk_grow: bool,
pub cpu_resize: bool,
pub memory_resize: bool,
pub secrets_update: bool,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct RuntimeCapabilities {
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub root_disk_grow: bool,
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub guest_flush_policy: bool,
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub optional_disk_integrity: bool,
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub branch_create: bool,
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub branch_memfd: bool,
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub pause_resume: bool,
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub disk_compact: bool,
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub disk_compact_owned: bool,
pub cpu_resize: bool,
pub memory_resize: bool,
pub secrets_update: bool,
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub checkpoint_create: bool,
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub disk_checkpoint_create: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum CheckpointCaptureIntent {
FullSnapshot,
Park,
TransparentTransfer,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CheckpointCreate {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub guest_flush: Option<microsandbox_types::GuestFlush>,
#[serde(default)]
pub record_integrity: bool,
pub checkpoint_id: String,
pub intent: CheckpointCaptureIntent,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CheckpointState {
pub checkpoint_id: String,
pub checkpoint_root: String,
pub path: PathBuf,
pub memory_mode: String,
pub memory_logical_bytes: u64,
pub memory_emitted_bytes: u64,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CheckpointResult {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub checkpoint: Option<CheckpointState>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub recovery_error: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DiskCheckpointCreate {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub guest_flush: Option<microsandbox_types::GuestFlush>,
pub checkpoint_id: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DiskCheckpointState {
pub checkpoint_id: String,
pub path: PathBuf,
pub disk: microsandbox_types::snapshot::disk::DiskGenerationManifest,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub owned_volumes: Vec<microsandbox_types::snapshot::OwnedVolumeCapture>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct BranchCreate {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub guest_flush: Option<microsandbox_types::GuestFlush>,
#[serde(default)]
pub record_integrity: bool,
pub branch_id: String,
pub child_name: String,
pub memory_cache_dir: PathBuf,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct BranchResult {
pub path: PathBuf,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct Pause {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub guest_flush: Option<microsandbox_types::GuestFlush>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct PauseState {
pub paused: bool,
pub recovery_required: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub capture_unavailable: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct RootDiskGrow {
pub size_bytes: u64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct RootDiskState {
pub filesystem_bytes: u64,
pub device_bytes: u64,
pub total_us: u64,
pub pause_us: u64,
pub guest_us: u64,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DiskCompact {
#[serde(default)]
pub target: microsandbox_types::DiskCompactionTarget,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub layers: Option<u64>,
#[serde(default)]
pub dry_run: bool,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct MemoryState {
pub boot_mib: u64,
pub target_mib: u64,
pub current_mib: u64,
pub max_mib: u64,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct CpuState {
pub possible: u32,
pub requested_online: u32,
pub actual_online: u32,
pub enforced: u32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct MemoryTarget {
pub total_mib: u64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct CpuTarget {
pub online: u32,
}
#[derive(Clone, Serialize, Deserialize, zeroize::Zeroize, zeroize::ZeroizeOnDrop)]
#[serde(transparent)]
pub struct SecretValue(pub String);
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "change", rename_all = "snake_case")]
pub enum SecretChange {
Rotate {
name: String,
value: SecretValue,
},
Remove {
name: String,
},
SetAllowedHosts {
name: String,
hosts: Vec<String>,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SecretsUpdate {
pub changes: Vec<SecretChange>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ErrorEffect {
None,
Unknown,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ControlError {
pub code: String,
pub message: String,
pub effect: ErrorEffect,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "outcome", rename_all = "snake_case")]
pub enum SecretsResult {
Complete {
applied_count: u32,
},
Failed {
applied_count: u32,
failed_index: u32,
error: ControlError,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "op", rename_all = "snake_case")]
pub enum ControlRequest {
Capabilities,
MemoryTarget {
total_mib: u64,
},
MemoryState,
CpuTarget {
online: u32,
},
CpuState,
SecretsUpdate {
changes: Vec<SecretChange>,
},
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct JsonControlResponse {
pub ok: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub error: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub memory: Option<MemoryState>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cpu: Option<CpuState>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub capabilities: Option<Capabilities>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub control_protocols: Option<Vec<String>>,
}
impl RuntimeCapabilities {
pub fn generation_one(self) -> Capabilities {
Capabilities {
root_disk_grow: self.root_disk_grow,
cpu_resize: self.cpu_resize,
memory_resize: self.memory_resize,
secrets_update: self.secrets_update,
}
}
}
impl ControlError {
pub fn rejected(code: impl Into<String>, message: impl Into<String>) -> Self {
Self {
code: code.into(),
message: message.into(),
effect: ErrorEffect::None,
}
}
}
impl std::fmt::Debug for SecretValue {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("[redacted]")
}
}