use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)]
pub enum DiskCompactionTarget {
#[default]
All,
Root,
Disk {
guest_path: String,
},
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct DiskCompactionDiskResult {
pub guest_path: String,
pub input_layers: usize,
pub selected_layers: usize,
pub output_layers: usize,
pub materialized_bytes: u64,
pub total_us: u64,
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct DiskCompactionResult {
pub dry_run: bool,
pub input_layers: usize,
pub selected_layers: usize,
pub output_layers: usize,
pub materialized_bytes: u64,
pub total_us: u64,
pub pause_us: u64,
pub disks: Vec<DiskCompactionDiskResult>,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ExternalMountRestorePolicy {
#[default]
Strict,
Relaxed,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ExternalMountWarning {
pub guest_path: String,
pub reason: String,
pub stale_inodes: Vec<u64>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn compaction_targets_have_closed_wire_shapes() {
for (target, json) in [
(DiskCompactionTarget::All, r#"{"kind":"all"}"#),
(DiskCompactionTarget::Root, r#"{"kind":"root"}"#),
(
DiskCompactionTarget::Disk {
guest_path: "/data".into(),
},
r#"{"kind":"disk","guest_path":"/data"}"#,
),
] {
assert_eq!(serde_json::to_string(&target).unwrap(), json);
assert_eq!(
serde_json::from_str::<DiskCompactionTarget>(json).unwrap(),
target
);
}
assert!(serde_json::from_str::<DiskCompactionTarget>(r#"{"kind":"disk"}"#).is_err());
assert!(
serde_json::from_str::<DiskCompactionTarget>(
r#"{"kind":"disk","guest_path":"/data","external":true}"#
)
.is_err()
);
}
#[test]
fn compaction_result_preserves_per_disk_metrics() {
let result = DiskCompactionResult {
dry_run: true,
disks: vec![DiskCompactionDiskResult {
guest_path: "/data".into(),
input_layers: 1,
output_layers: 1,
..Default::default()
}],
..Default::default()
};
let encoded = serde_json::to_string(&result).unwrap();
let decoded: DiskCompactionResult = serde_json::from_str(&encoded).unwrap();
assert!(decoded.dry_run);
assert_eq!(decoded.disks[0].guest_path, "/data");
assert_eq!(decoded.disks[0].selected_layers, 0);
assert!(serde_json::from_str::<DiskCompactionResult>(r#"{"dry_run":false,"input_layers":1,"selected_layers":0,"output_layers":1,"materialized_bytes":0,"total_us":0,"pause_us":0}"#).is_err());
}
}
pub mod cloud_manifest;
pub mod disk;
pub mod legacy;
pub mod manifest;
pub mod owned;
mod restore_defaults;
pub use manifest::*;
pub use owned::{
OWNED_VOLUMES_EXTENSION, OwnedDirectoryPayload, OwnedMountSnapshot, OwnedVolumeCapture,
OwnedVolumeData, validate_owned_volumes,
};
pub use restore_defaults::{RESTORE_DEFAULTS_EXTENSION, RestoreDefaults};