Skip to content

Commit 0232ecb

Browse files
committed
provisioning: Add filesystem formatting support
Signed-off-by: Ikey Doherty <[email protected]>
1 parent 4243f9c commit 0232ecb

File tree

3 files changed

+131
-1
lines changed

3 files changed

+131
-1
lines changed

crates/provisioning/src/commands/create_partition.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
// SPDX-License-Identifier: MPL-2.0
55

66
use crate::{
7-
get_kdl_entry, get_kdl_property, get_property_str, Constraints, Context, FromKdlProperty, FromKdlType,
7+
get_kdl_entry, get_kdl_property, get_property_str, Constraints, Context, Filesystem, FromKdlProperty, FromKdlType,
88
PartitionRole, PartitionTypeGuid, PartitionTypeKDL,
99
};
1010

@@ -25,6 +25,9 @@ pub struct Command {
2525

2626
/// Constraints for the partition
2727
pub constraints: Constraints,
28+
29+
/// The filesystem to format the partition with
30+
pub filesystem: Option<Filesystem>,
2831
}
2932

3033
/// Generate a command to create a partition
@@ -39,6 +42,7 @@ pub(crate) fn parse(context: Context<'_>) -> Result<super::Command, crate::Error
3942

4043
let mut constraints = Constraints::default();
4144
let mut partition_type = None;
45+
let mut filesystem = None;
4246

4347
for child in context.node.iter_children() {
4448
match child.name().value() {
@@ -48,6 +52,7 @@ pub(crate) fn parse(context: Context<'_>) -> Result<super::Command, crate::Error
4852
PartitionTypeKDL::GUID => Some(PartitionTypeGuid::from_kdl_node(child)?),
4953
}
5054
}
55+
"filesystem" => filesystem = Some(Filesystem::from_kdl_node(child)?),
5156
_ => {
5257
return Err(crate::UnsupportedNode {
5358
at: child.span(),
@@ -72,5 +77,6 @@ pub(crate) fn parse(context: Context<'_>) -> Result<super::Command, crate::Error
7277
role,
7378
constraints,
7479
partition_type,
80+
filesystem,
7581
})))
7682
}

crates/provisioning/src/types.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ mod units;
1818
pub use units::*;
1919
pub mod constraints;
2020
pub use constraints::*;
21+
pub mod filesystem;
22+
pub use filesystem::*;
2123
mod partition_type;
2224
pub use partition_type::*;
2325

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// SPDX-FileCopyrightText: Copyright © 2025 Serpent OS Developers
2+
// SPDX-FileCopyrightText: Copyright © 2025 AerynOS Developers
3+
//
4+
// SPDX-License-Identifier: MPL-2.0
5+
6+
use std::{fmt, str::FromStr};
7+
8+
use crate::{get_kdl_entry, kdl_value_to_string};
9+
10+
use super::FromKdlProperty;
11+
12+
/// The filesystem information for a partition
13+
/// This is used to format the partition with a filesystem
14+
///
15+
/// The "any" filesystem type is used to indicate that any filesystem is acceptable.
16+
#[derive(Debug, PartialEq)]
17+
pub struct Filesystem {
18+
/// The filesystem type
19+
pub filesystem_type: FilesystemType,
20+
21+
/// The label of the filesystem
22+
pub label: Option<String>,
23+
24+
/// The UUID of the filesystem
25+
pub uuid: Option<String>,
26+
}
27+
28+
/// The filesystem type for a partition
29+
#[derive(Debug, PartialEq, Default)]
30+
pub enum FilesystemType {
31+
/// FAT32 filesystem
32+
Fat32,
33+
34+
/// F2FS filesystem
35+
F2fs,
36+
37+
/// EXT4 filesystem
38+
Ext4,
39+
40+
/// XFS filesystem
41+
Xfs,
42+
43+
/// Swap partition
44+
Swap,
45+
46+
/// Any filesystem
47+
#[default]
48+
Any,
49+
}
50+
51+
impl fmt::Display for FilesystemType {
52+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53+
match self {
54+
Self::Fat32 => f.write_str("fat32"),
55+
Self::Ext4 => f.write_str("ext4"),
56+
Self::F2fs => f.write_str("f2fs"),
57+
Self::Xfs => f.write_str("xfs"),
58+
Self::Swap => f.write_str("swap"),
59+
Self::Any => f.write_str("any"),
60+
}
61+
}
62+
}
63+
64+
impl FromStr for FilesystemType {
65+
type Err = crate::Error;
66+
67+
/// Attempt to convert a string to a filesystem type
68+
fn from_str(value: &str) -> Result<Self, Self::Err> {
69+
match value {
70+
"fat32" => Ok(Self::Fat32),
71+
"ext4" => Ok(Self::Ext4),
72+
"f2fs" => Ok(Self::F2fs),
73+
"xfs" => Ok(Self::Xfs),
74+
"swap" => Ok(Self::Swap),
75+
"any" => Ok(Self::Any),
76+
_ => Err(crate::Error::UnknownVariant),
77+
}
78+
}
79+
}
80+
81+
impl FromKdlProperty<'_> for FilesystemType {
82+
fn from_kdl_property(entry: &kdl::KdlEntry) -> Result<Self, crate::Error> {
83+
let value = kdl_value_to_string(entry)?;
84+
let v = value.parse().map_err(|_| crate::UnsupportedValue {
85+
at: entry.span(),
86+
advice: Some("'fat32', 'ext4', 'f2fs', 'xfs' 'swap' and 'any' are supported".into()),
87+
})?;
88+
Ok(v)
89+
}
90+
}
91+
92+
impl Filesystem {
93+
pub fn from_kdl_node(node: &kdl::KdlNode) -> Result<Self, crate::Error> {
94+
let mut filesystem_type = None;
95+
let mut label = None;
96+
let mut uuid = None;
97+
98+
for entry in node.iter_children() {
99+
match entry.name().value() {
100+
"type" => filesystem_type = Some(FilesystemType::from_kdl_property(get_kdl_entry(entry, &0)?)?),
101+
"label" => label = Some(kdl_value_to_string(get_kdl_entry(entry, &0)?)?),
102+
"uuid" => uuid = Some(kdl_value_to_string(get_kdl_entry(entry, &0)?)?),
103+
_ => {
104+
return Err(crate::UnsupportedNode {
105+
at: entry.span(),
106+
name: entry.name().value().into(),
107+
}
108+
.into())
109+
}
110+
}
111+
}
112+
113+
Ok(Self {
114+
filesystem_type: filesystem_type.ok_or(crate::UnsupportedNode {
115+
at: node.span(),
116+
name: "type".into(),
117+
})?,
118+
label,
119+
uuid,
120+
})
121+
}
122+
}

0 commit comments

Comments
 (0)