aleph_types/message/execution/
volume.rs1use crate::item_hash::ItemHash;
2use crate::storage_size::{MemorySize, MiB, gigabyte_to_mebibyte};
3use crate::toolkit::serde::default_true;
4use serde::{Deserialize, Serialize};
5use std::path::PathBuf;
6
7#[derive(thiserror::Error, Debug)]
8pub enum VolumeError {
9 #[error("value {size} is out of range ({min}..={max})")]
10 OutOfRange { size: u64, min: u64, max: u64 },
11}
12
13pub trait IsReadOnly {
14 fn is_read_only() -> bool;
15}
16
17#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
18pub struct BaseVolume {
19 #[serde(default)]
20 pub comment: Option<String>,
21 #[serde(default)]
22 pub mount: Option<PathBuf>,
23}
24
25#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
26pub struct ImmutableVolume {
27 #[serde(flatten)]
28 pub base: BaseVolume,
29 #[serde(default, rename = "ref")]
30 pub reference: Option<ItemHash>,
31 #[serde(default = "default_true")]
32 pub use_latest: bool,
33}
34
35impl IsReadOnly for ImmutableVolume {
36 fn is_read_only() -> bool {
37 true
38 }
39}
40
41#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
42#[serde(try_from = "u64", into = "u64")]
43pub struct EphemeralVolumeSize(MiB);
44
45impl EphemeralVolumeSize {
46 const MIN: u64 = 1;
47 const MAX: u64 = 1000;
48}
49
50impl TryFrom<u64> for EphemeralVolumeSize {
51 type Error = VolumeError;
52
53 fn try_from(size: u64) -> Result<Self, Self::Error> {
54 if (Self::MIN..=Self::MAX).contains(&size) {
55 Ok(Self(MiB::from_units(size)))
56 } else {
57 Err(VolumeError::OutOfRange {
58 size,
59 min: Self::MIN,
60 max: Self::MAX,
61 })
62 }
63 }
64}
65
66impl From<EphemeralVolumeSize> for u64 {
67 fn from(size: EphemeralVolumeSize) -> Self {
68 size.0.units()
69 }
70}
71
72#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
74pub struct EphemeralVolume {
75 #[serde(flatten)]
76 pub base: BaseVolume,
77 ephemeral: bool,
78 size_mib: EphemeralVolumeSize,
79}
80
81impl IsReadOnly for EphemeralVolume {
82 fn is_read_only() -> bool {
83 false
84 }
85}
86
87#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
89pub struct ParentVolume {
90 #[serde(rename = "ref")]
91 pub reference: ItemHash,
92 #[serde(default = "default_true")]
93 pub use_latest: bool,
94}
95
96#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
98#[serde(rename_all = "lowercase")]
99pub enum VolumePersistence {
100 Host,
101 Store,
102}
103
104#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
105#[serde(try_from = "u64", into = "u64")]
106pub struct PersistentVolumeSize(MiB);
107
108impl PersistentVolumeSize {
109 const MIN: u64 = 1;
110 const MAX: u64 = gigabyte_to_mebibyte(2048);
111}
112
113impl TryFrom<u64> for PersistentVolumeSize {
114 type Error = VolumeError;
115
116 fn try_from(size: u64) -> Result<Self, Self::Error> {
117 if (Self::MIN..=Self::MAX).contains(&size) {
118 Ok(Self(MiB::from_units(size)))
119 } else {
120 Err(VolumeError::OutOfRange {
121 size,
122 min: Self::MIN,
123 max: Self::MAX,
124 })
125 }
126 }
127}
128
129impl From<PersistentVolumeSize> for u64 {
130 fn from(size: PersistentVolumeSize) -> Self {
131 size.0.units()
132 }
133}
134
135impl From<MiB> for PersistentVolumeSize {
136 fn from(size: MiB) -> Self {
137 Self(size)
138 }
139}
140
141#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
142pub struct PersistentVolume {
143 #[serde(flatten)]
144 pub base: BaseVolume,
145 #[serde(default)]
146 pub parent: Option<ParentVolume>,
147 #[serde(default)]
148 pub persistence: Option<VolumePersistence>,
149 #[serde(default)]
150 pub name: Option<String>,
151 size_mib: PersistentVolumeSize,
152}
153
154impl IsReadOnly for PersistentVolume {
155 fn is_read_only() -> bool {
156 false
157 }
158}
159
160#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
161#[serde(untagged)]
162pub enum MachineVolume {
163 Immutable(ImmutableVolume),
164 Ephemeral(EphemeralVolume),
165 Persistent(PersistentVolume),
166}
167
168#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
173pub struct RootfsVolume {
174 pub parent: ParentVolume,
175 pub persistence: VolumePersistence,
176 pub size_mib: PersistentVolumeSize,
177 #[serde(default)]
178 pub forgotten_by: Option<Vec<ItemHash>>,
179}
180
181#[cfg(test)]
182mod tests {
183 use super::*;
184
185 #[test]
186 fn test_is_read_only() {
188 assert!(ImmutableVolume::is_read_only());
189 assert!(!EphemeralVolume::is_read_only());
190 assert!(!PersistentVolume::is_read_only());
191 }
192}