diff --git a/README.md b/README.md index bd3df8b..041200e 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,8 @@ Dependencies will be handled for you if you install alma from AUR. sudo alma create /dev/disk/by-id/usb-Generic_USB_Flash_Disk-0:0 ``` -This will wipe the entire disk and create a bootable installation of Arch Linux. +This will wipe the entire disk and create a bootable installation of Arch Linux. You can use either +removable devices or loop devices. As a precaution, ALMA will not wipe non-removable devices. After the installation is done you can either boot from it immediately or use `arch-chroot` to perform further customizations before your first boot. diff --git a/src/block.rs b/src/block.rs index 4845c39..a02297c 100644 --- a/src/block.rs +++ b/src/block.rs @@ -23,7 +23,12 @@ impl BlockDevice { path, real_path, device_name ); - Ok(Self { name: device_name }) + let _self = Self { name: device_name }; + if !(_self.is_removable()? || _self.is_loop_device()) { + return Err(ErrorKind::DangerousDevice)?; + } + + Ok(_self) } fn sys_path(&self) -> PathBuf { @@ -32,7 +37,7 @@ impl BlockDevice { path } - pub fn removable(&self) -> Result { + fn is_removable(&self) -> Result { let mut path = self.sys_path(); path.push("removable"); @@ -43,6 +48,12 @@ impl BlockDevice { Ok(result == "1\n") } + fn is_loop_device(&self) -> bool { + let mut path = self.sys_path(); + path.push("loop"); + path.exists() + } + pub fn device_path(&self) -> PathBuf { let mut path = PathBuf::from("/dev"); path.push(self.name.clone()); diff --git a/src/error.rs b/src/error.rs index 4f413e9..9ef9a78 100644 --- a/src/error.rs +++ b/src/error.rs @@ -14,8 +14,8 @@ pub enum ErrorKind { #[fail(display = "Invalid device name")] InvalidDeviceName, - #[fail(display = "The given block device is not removable")] - NotRemovableDevice, + #[fail(display = "The given block device is neither removable nor a loop device")] + DangerousDevice, #[fail(display = "Partition {} does not exist", _0)] NoSuchPartition(u8), diff --git a/src/main.rs b/src/main.rs index 3d04011..44697f7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -62,7 +62,7 @@ enum Command { struct CreateCommand { /// Path starting with /dev/disk/by-id for the USB drive #[structopt(parse(from_os_str),)] - disk: PathBuf, + block_device: PathBuf, /// Additional pacakges to install #[structopt(short = "p", long = "extra-packages", value_name = "package",)] @@ -77,7 +77,7 @@ struct CreateCommand { struct ChrootCommand { /// Path starting with /dev/disk/by-id for the USB drive #[structopt(parse(from_os_str),)] - disk: PathBuf, + block_device: PathBuf, } fn create(command: CreateCommand) -> Result<(), Error> { @@ -88,18 +88,14 @@ fn create(command: CreateCommand) -> Result<(), Error> { let mkfat = Tool::find("mkfs.fat")?; let mkbtrfs = Tool::find("mkfs.btrfs")?; - let disk = block::BlockDevice::from_path(command.disk)?; - - if !disk.removable()? { - Err(ErrorKind::NotRemovableDevice)?; - } + 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 = disk.device_path(); + let disk_path = block_device.device_path(); - info!("Partitioning the disk"); + info!("Partitioning the block device"); debug!("{:?}", disk_path); sgdisk @@ -118,14 +114,14 @@ fn create(command: CreateCommand) -> Result<(), Error> { thread::sleep(Duration::from_millis(1000)); info!("Formatting filesystems"); - let boot_partition = disk.partition_device_path(2)?; + let boot_partition = block_device.partition_device_path(2)?; mkfat .execute() .arg("-F32") .arg(&boot_partition) .run(ErrorKind::Formatting)?; - let root_partition = disk.partition_device_path(3)?; + let root_partition = block_device.partition_device_path(3)?; mkbtrfs .execute() .arg("-f") @@ -219,18 +215,14 @@ fn create(command: CreateCommand) -> Result<(), Error> { fn chroot(command: ChrootCommand) -> Result<(), Error> { let arch_chroot = Tool::find("arch-chroot")?; - let disk = block::BlockDevice::from_path(command.disk)?; - - if !disk.removable()? { - Err(ErrorKind::NotRemovableDevice)?; - } + 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 = disk.partition_device_path(3)?; + let root_partition = block_device.partition_device_path(3)?; mount_stack .mount( &root_partition, @@ -239,7 +231,7 @@ fn chroot(command: ChrootCommand) -> Result<(), Error> { None, ).context(ErrorKind::Mounting)?; - let boot_partition = disk.partition_device_path(2)?; + let boot_partition = block_device.partition_device_path(2)?; mount_stack .mount(&boot_partition, &boot_point, Filesystem::Vfat, None) .context(ErrorKind::Mounting)?;