diff --git a/src/alma.rs b/src/alma.rs new file mode 100644 index 0000000..b404eba --- /dev/null +++ b/src/alma.rs @@ -0,0 +1,45 @@ +use super::block::BlockDevice; +use super::error::{Error, ErrorKind}; +use super::mountstack::{Filesystem, MountStack}; +use failure::ResultExt; +use log::info; +use std::fs; +use std::path::{Path, PathBuf}; + +pub struct ALMA { + block: BlockDevice, +} + +impl ALMA { + pub fn new(block: BlockDevice) -> Self { + Self { block } + } + + pub fn mount<'a>(&self, path: &'a Path) -> Result, Error> { + let mut mount_stack = MountStack::new(); + + info!("Mounting filesystems to {}", path.display()); + mount_stack + .mount( + &PathBuf::from(&self.block.partition_device_path(3)?), + path, + Filesystem::Btrfs, + None, + ).context(ErrorKind::Mounting)?; + + let boot_point = path.join("boot"); + if !boot_point.exists() { + fs::create_dir(&boot_point).context(ErrorKind::CreateBoot)?; + } + + mount_stack + .mount( + &self.block.partition_device_path(2)?, + boot_point, + Filesystem::Vfat, + None, + ).context(ErrorKind::Mounting)?; + + Ok(mount_stack) + } +} diff --git a/src/main.rs b/src/main.rs index 8ab40e6..669741d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,16 +7,17 @@ extern crate tempfile; extern crate which; use nix::sys::signal; +mod alma; mod block; mod error; mod mountstack; mod process; mod tool; +use alma::ALMA; use error::*; use failure::{Fail, ResultExt}; use log::{debug, error, info, warn}; -use mountstack::{Filesystem, MountStack}; use process::CommandExt; use simplelog::*; use std::fs; @@ -91,8 +92,7 @@ fn create(command: CreateCommand) -> Result<(), Error> { let block_device = block::BlockDevice::from_path(command.block_device)?; let mount_point = tempdir().context(ErrorKind::TmpDirError)?; - let boot_point = mount_point.path().join("boot"); - let mut mount_stack = MountStack::new(); + let disk_path = block_device.device_path(); info!("Partitioning the block device"); @@ -128,20 +128,8 @@ fn create(command: CreateCommand) -> Result<(), Error> { .arg(&root_partition) .run(ErrorKind::Formatting)?; - info!("Mounting filesystems to {}", mount_point.path().display()); - mount_stack - .mount( - &PathBuf::from(&root_partition), - &mount_point.path(), - Filesystem::Btrfs, - None, - ).context(ErrorKind::Mounting)?; - - fs::create_dir(&boot_point).context(ErrorKind::CreateBoot)?; - - mount_stack - .mount(&boot_partition, &boot_point, Filesystem::Vfat, None) - .context(ErrorKind::Mounting)?; + let alma = ALMA::new(block_device); + let mut mount_stack = alma.mount(mount_point.path())?; info!("Bootstrapping system"); pacstrap @@ -218,23 +206,8 @@ fn chroot(command: ChrootCommand) -> Result<(), Error> { let block_device = block::BlockDevice::from_path(command.block_device)?; let mount_point = tempdir().context(ErrorKind::TmpDirError)?; - let boot_point = mount_point.path().join("boot"); - let mut mount_stack = MountStack::new(); - - info!("Mounting filesystems to {}", mount_point.path().display()); - let root_partition = block_device.partition_device_path(3)?; - mount_stack - .mount( - &root_partition, - &mount_point.path(), - Filesystem::Btrfs, - None, - ).context(ErrorKind::Mounting)?; - - let boot_partition = block_device.partition_device_path(2)?; - mount_stack - .mount(&boot_partition, &boot_point, Filesystem::Vfat, None) - .context(ErrorKind::Mounting)?; + let alma = ALMA::new(block_device); + let mut mount_stack = alma.mount(mount_point.path())?; arch_chroot .execute() @@ -242,6 +215,8 @@ fn chroot(command: ChrootCommand) -> Result<(), Error> { .run(ErrorKind::Interactive)?; info!("Unmounting filesystems"); + mount_stack.umount()?; + Ok(()) } diff --git a/src/mountstack.rs b/src/mountstack.rs index 61137ae..b39bbba 100644 --- a/src/mountstack.rs +++ b/src/mountstack.rs @@ -3,6 +3,7 @@ use failure::Fail; use log::{debug, warn}; use nix; use nix::mount::{mount, umount, MsFlags}; +use std::borrow::Cow; use std::path::Path; #[derive(Debug)] @@ -21,7 +22,7 @@ impl Filesystem { } pub struct MountStack<'a> { - targets: Vec<&'a Path>, + targets: Vec>, } impl<'a> MountStack<'a> { @@ -32,17 +33,19 @@ impl<'a> MountStack<'a> { } #[must_use] - pub fn mount( + pub fn mount>>( &mut self, source: &Path, - target: &'a Path, + target: T, filesystem: Filesystem, options: Option<&str>, ) -> nix::Result<()> { + let target = target.into(); + debug!("Mounting {:?} ({:?}) to {:?}", source, filesystem, target); mount( Some(source), - target, + target.as_ref(), Some(filesystem.to_type()), MsFlags::empty(), options, @@ -56,7 +59,7 @@ impl<'a> MountStack<'a> { while let Some(target) = self.targets.pop() { debug!("Unmounting {}", target.display()); - if let Err(e) = umount(target) { + if let Err(e) = umount(target.as_ref()) { warn!("Unable to umount {}: {}", target.display(), e); result = Err(Error::from(e.context(ErrorKind::UmountFailure))); };