Skip to content

Commit 87b4ec3

Browse files
committed
parse volumes
1 parent e859e56 commit 87b4ec3

File tree

2 files changed

+73
-9
lines changed

2 files changed

+73
-9
lines changed

src/create_distrobox_dialog.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -394,12 +394,15 @@ impl CreateDistroboxDialog {
394394
.iter()
395395
.filter_map(|entry| {
396396
if !entry.text().is_empty() {
397-
Some(entry.text().to_string())
397+
match entry.text().parse::<distrobox::Volume>() {
398+
Ok(volume) => Some(Ok(volume)),
399+
Err(e) => Some(Err(e)),
400+
}
398401
} else {
399402
None
400403
}
401404
})
402-
.collect::<Vec<_>>();
405+
.collect::<Result<Vec<_>, _>>()?;
403406

404407
let name = CreateArgName::new(&imp.name_row.text())?;
405408

@@ -429,7 +432,7 @@ impl CreateDistroboxDialog {
429432
pub fn build_volumes_group(&self) -> adw::PreferencesGroup {
430433
let volumes_group = adw::PreferencesGroup::new();
431434
volumes_group.set_title("Volumes");
432-
volumes_group.set_description(Some("Specify volumes in the format 'dest_dir:source_dir'"));
435+
volumes_group.set_description(Some("Specify volumes in the format 'host_path:container_path'"));
433436

434437
let add_volume_button = adw::ButtonRow::builder().title("Add Volume").build();
435438
add_volume_button.connect_activated(clone!(

src/distrobox/mod.rs

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,66 @@ pub struct CreateArgs {
183183
pub home_path: Option<String>,
184184
pub image: String,
185185
pub name: CreateArgName,
186-
pub volumes: Vec<String>,
186+
pub volumes: Vec<Volume>,
187+
}
188+
189+
#[derive(Debug, Clone, PartialEq)]
190+
pub enum VolumeMode {
191+
ReadOnly,
192+
}
193+
194+
impl std::fmt::Display for VolumeMode {
195+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
196+
match self {
197+
VolumeMode::ReadOnly => write!(f, "ro"),
198+
}
199+
}
200+
}
201+
202+
#[derive(Debug, Clone, PartialEq)]
203+
pub struct Volume {
204+
pub host_path: String,
205+
pub container_path: String,
206+
pub mode: Option<VolumeMode>,
207+
}
208+
209+
impl FromStr for Volume {
210+
type Err = Error;
211+
212+
fn from_str(s: &str) -> Result<Self, Self::Err> {
213+
let parts: Vec<&str> = s.split(':').collect();
214+
match parts.as_slice() {
215+
[host] => Ok(Volume {
216+
host_path: host.to_string(),
217+
container_path: host.to_string(),
218+
mode: None,
219+
}),
220+
[host, target] => Ok(Volume {
221+
host_path: host.to_string(),
222+
container_path: target.to_string(),
223+
mode: None,
224+
}),
225+
[host, target, "ro"] => Ok(Volume {
226+
host_path: host.to_string(),
227+
container_path: target.to_string(),
228+
mode: Some(VolumeMode::ReadOnly),
229+
}),
230+
_ => Err(Error::InvalidField(
231+
"volume".into(),
232+
format!("Invalid volume descriptor: {}", s),
233+
)),
234+
}
235+
}
236+
}
237+
238+
impl std::fmt::Display for Volume {
239+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
240+
write!(f, "{}:{}", self.host_path, self.container_path)?;
241+
if let Some(mode) = &self.mode {
242+
write!(f, ":{}", mode)?;
243+
}
244+
Ok(())
245+
}
187246
}
188247

189248
#[derive(thiserror::Error, Debug)]
@@ -688,7 +747,7 @@ impl Distrobox {
688747
cmd.arg("--home").arg(home_path);
689748
}
690749
for volume in args.volumes {
691-
cmd.arg("--volume").arg(volume);
750+
cmd.arg("--volume").arg(volume.to_string());
692751
}
693752
self.cmd_spawn(cmd)
694753
}
@@ -932,12 +991,14 @@ Categories=Utility;Network;
932991
init: true,
933992
nvidia: true,
934993
home_path: Some("/home/me".into()),
935-
volumes: vec!["/mnt/sdb1".into(), "/mnt/sdb4".into()],
994+
volumes: vec![
995+
Volume::from_str("/mnt/sdb1:/mnt/sdb1")?,
996+
Volume::from_str("/mnt/sdb4:/mnt/sdb4:ro")?,
997+
],
936998
..Default::default()
937999
};
938-
939-
block_on(db.create(args))?;
940-
let expected = "\"distrobox\" [\"create\", \"--yes\", \"--image\", \"docker.io/library/ubuntu:latest\", \"--init\", \"--nvidia\", \"--home\", \"/home/me\", \"--volume\", \"/mnt/sdb1\", \"--volume\", \"/mnt/sdb4\"]";
1000+
smol::block_on(db.create(args))?;
1001+
let expected = "\"distrobox\" [\"create\", \"--yes\", \"--image\", \"docker.io/library/ubuntu:latest\", \"--init\", \"--nvidia\", \"--home\", \"/home/me\", \"--volume\", \"/mnt/sdb1:/mnt/sdb1\", \"--volume\", \"/mnt/sdb4:/mnt/sdb4:ro\"]";
9411002
assert_eq!(output_tracker.items()[0], expected);
9421003
Ok(())
9431004
}

0 commit comments

Comments
 (0)