aleph_types/message/execution/
volume.rs1use crate::item_hash::ItemHash;
2use crate::memory_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(rename = "ref")]
30 pub reference: 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, Copy, 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
72impl From<MiB> for EphemeralVolumeSize {
73 fn from(size: MiB) -> Self {
74 Self(size)
75 }
76}
77
78impl From<EphemeralVolumeSize> for MiB {
79 fn from(value: EphemeralVolumeSize) -> Self {
80 value.0
81 }
82}
83
84#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
86pub struct EphemeralVolume {
87 #[serde(flatten)]
88 pub base: BaseVolume,
89 ephemeral: bool,
90 pub size_mib: EphemeralVolumeSize,
91}
92
93impl IsReadOnly for EphemeralVolume {
94 fn is_read_only() -> bool {
95 false
96 }
97}
98
99#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
101pub struct ParentVolume {
102 #[serde(rename = "ref")]
103 pub reference: ItemHash,
104 #[serde(default = "default_true")]
105 pub use_latest: bool,
106}
107
108#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
110#[serde(rename_all = "lowercase")]
111pub enum VolumePersistence {
112 Host,
113 Store,
114}
115
116#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
117#[serde(try_from = "u64", into = "u64")]
118pub struct PersistentVolumeSize(MiB);
119
120impl PersistentVolumeSize {
121 const MIN: u64 = 1;
122 const MAX: u64 = gigabyte_to_mebibyte(2048);
123}
124
125impl TryFrom<u64> for PersistentVolumeSize {
126 type Error = VolumeError;
127
128 fn try_from(size: u64) -> Result<Self, Self::Error> {
129 if (Self::MIN..=Self::MAX).contains(&size) {
130 Ok(Self(MiB::from_units(size)))
131 } else {
132 Err(VolumeError::OutOfRange {
133 size,
134 min: Self::MIN,
135 max: Self::MAX,
136 })
137 }
138 }
139}
140
141impl From<PersistentVolumeSize> for u64 {
142 fn from(size: PersistentVolumeSize) -> Self {
143 size.0.units()
144 }
145}
146
147impl From<MiB> for PersistentVolumeSize {
148 fn from(size: MiB) -> Self {
149 Self(size)
150 }
151}
152
153impl From<PersistentVolumeSize> for MiB {
154 fn from(value: PersistentVolumeSize) -> Self {
155 value.0
156 }
157}
158
159#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
160pub struct PersistentVolume {
161 #[serde(flatten)]
162 pub base: BaseVolume,
163 #[serde(default)]
164 pub parent: Option<ParentVolume>,
165 #[serde(default)]
166 pub persistence: Option<VolumePersistence>,
167 #[serde(default)]
168 pub name: Option<String>,
169 pub size_mib: PersistentVolumeSize,
170}
171
172impl IsReadOnly for PersistentVolume {
173 fn is_read_only() -> bool {
174 false
175 }
176}
177
178#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
179#[serde(untagged)]
180pub enum MachineVolume {
181 Immutable(ImmutableVolume),
182 Ephemeral(EphemeralVolume),
183 Persistent(PersistentVolume),
184}
185
186#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
191pub struct RootfsVolume {
192 pub parent: ParentVolume,
193 pub persistence: VolumePersistence,
194 pub size_mib: PersistentVolumeSize,
195 #[serde(default)]
196 pub forgotten_by: Option<Vec<ItemHash>>,
197}
198
199#[cfg(test)]
200mod tests {
201 use super::*;
202
203 #[test]
204 fn test_is_read_only() {
206 assert!(ImmutableVolume::is_read_only());
207 assert!(!EphemeralVolume::is_read_only());
208 assert!(!PersistentVolume::is_read_only());
209 }
210}