mirror of
https://github.com/philmmanjaro/alma.git
synced 2025-12-06 19:39:20 +01:00
Migrate ALMA to anyhow (#54)
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
use super::markers::BlockDevice;
|
||||
use crate::error::{Error, ErrorKind};
|
||||
use crate::process::CommandExt;
|
||||
use crate::tool::Tool;
|
||||
use failure::ResultExt;
|
||||
use anyhow::Context;
|
||||
use log::{debug, warn};
|
||||
use std::fs;
|
||||
use std::io::Read;
|
||||
@@ -21,14 +20,15 @@ pub struct EncryptedDevice<'t, 'o> {
|
||||
}
|
||||
|
||||
impl<'t, 'o> EncryptedDevice<'t, 'o> {
|
||||
pub fn prepare(cryptsetup: &Tool, device: &dyn BlockDevice) -> Result<(), Error> {
|
||||
pub fn prepare(cryptsetup: &Tool, device: &dyn BlockDevice) -> anyhow::Result<()> {
|
||||
debug!("Preparing encrypted device in {}", device.path().display());
|
||||
cryptsetup
|
||||
.execute()
|
||||
.arg("luksFormat")
|
||||
.arg("-q")
|
||||
.arg(device.path())
|
||||
.run(ErrorKind::LuksSetup)?;
|
||||
.run()
|
||||
.context("Error setting up an encrypted device")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -37,7 +37,7 @@ impl<'t, 'o> EncryptedDevice<'t, 'o> {
|
||||
cryptsetup: &'t Tool,
|
||||
device: &'o dyn BlockDevice,
|
||||
name: String,
|
||||
) -> Result<EncryptedDevice<'t, 'o>, Error> {
|
||||
) -> anyhow::Result<EncryptedDevice<'t, 'o>> {
|
||||
debug!(
|
||||
"Opening encrypted device {} as {}",
|
||||
device.path().display(),
|
||||
@@ -48,7 +48,8 @@ impl<'t, 'o> EncryptedDevice<'t, 'o> {
|
||||
.arg("open")
|
||||
.arg(device.path())
|
||||
.arg(&name)
|
||||
.run(ErrorKind::LuksOpen)?;
|
||||
.run()
|
||||
.context("Error opening the encrypted device")?;
|
||||
|
||||
let path = PathBuf::from("/dev/mapper").join(&name);
|
||||
Ok(Self {
|
||||
@@ -59,13 +60,14 @@ impl<'t, 'o> EncryptedDevice<'t, 'o> {
|
||||
})
|
||||
}
|
||||
|
||||
fn _close(&mut self) -> Result<(), Error> {
|
||||
fn _close(&mut self) -> anyhow::Result<()> {
|
||||
debug!("Closing encrypted device {}", self.name);
|
||||
self.cryptsetup
|
||||
.execute()
|
||||
.arg("close")
|
||||
.arg(&self.name)
|
||||
.run(ErrorKind::LuksClose)?;
|
||||
.run()
|
||||
.context("Error closing the encrypted device")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -85,16 +87,16 @@ impl<'t, 'o> BlockDevice for EncryptedDevice<'t, 'o> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_encrypted_device(device: &dyn BlockDevice) -> Result<bool, Error> {
|
||||
pub fn is_encrypted_device(device: &dyn BlockDevice) -> anyhow::Result<bool> {
|
||||
let mut f = fs::OpenOptions::new()
|
||||
.read(true)
|
||||
.write(false)
|
||||
.open(device.path())
|
||||
.context(ErrorKind::LuksDetection)?;
|
||||
.context("Error detecting whether the root partition is an encrypted device")?;
|
||||
|
||||
let mut buffer = [0; 6];
|
||||
f.read_exact(&mut buffer)
|
||||
.context(ErrorKind::LuksDetection)?;
|
||||
.context("Error detecting whether the root partition is an encrypted device")?;
|
||||
|
||||
Ok(buffer == LUKS_MAGIC_1 || buffer == LUKS_MAGIC_2)
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
use super::markers::BlockDevice;
|
||||
use crate::{
|
||||
error::{Error, ErrorKind},
|
||||
process::CommandExt,
|
||||
tool::Tool,
|
||||
};
|
||||
use crate::{process::CommandExt, tool::Tool};
|
||||
use anyhow::Context;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum FilesystemType {
|
||||
@@ -31,14 +28,14 @@ impl<'a> Filesystem<'a> {
|
||||
block: &'a dyn BlockDevice,
|
||||
fs_type: FilesystemType,
|
||||
mkfs: &Tool,
|
||||
) -> Result<Self, Error> {
|
||||
) -> anyhow::Result<Self> {
|
||||
let mut command = mkfs.execute();
|
||||
match fs_type {
|
||||
FilesystemType::Ext4 => command.arg("-F").arg(block.path()),
|
||||
FilesystemType::Vfat => command.arg("-F32").arg(block.path()),
|
||||
};
|
||||
|
||||
command.run(ErrorKind::Formatting)?;
|
||||
command.run().context("Error formatting filesystem")?;
|
||||
|
||||
Ok(Self { fs_type, block })
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use crate::error::{Error, ErrorKind};
|
||||
use crate::tool::Tool;
|
||||
use failure::ResultExt;
|
||||
use anyhow::{anyhow, Context};
|
||||
use log::info;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
@@ -11,20 +10,24 @@ pub struct LoopDevice {
|
||||
}
|
||||
|
||||
impl LoopDevice {
|
||||
pub fn create(file: &Path) -> Result<Self, Error> {
|
||||
pub fn create(file: &Path) -> anyhow::Result<Self> {
|
||||
let losetup = Tool::find("losetup")?;
|
||||
let output = losetup
|
||||
.execute()
|
||||
.args(&["--find", "-P", "--show"])
|
||||
.arg(file)
|
||||
.output()
|
||||
.context(ErrorKind::Image)?;
|
||||
.context("Error creating the image")?;
|
||||
|
||||
if !output.status.success() {
|
||||
return Err(ErrorKind::Losetup(String::from_utf8(output.stderr).unwrap()).into());
|
||||
return Err(anyhow!(String::from_utf8(output.stderr)?));
|
||||
}
|
||||
|
||||
let path = PathBuf::from(String::from_utf8(output.stdout).unwrap().trim());
|
||||
let path = PathBuf::from(
|
||||
String::from_utf8(output.stdout)
|
||||
.context("Output not valid UTF-8")?
|
||||
.trim(),
|
||||
);
|
||||
info!("Mounted {} to {}", file.display(), path.display());
|
||||
|
||||
Ok(LoopDevice { path, losetup })
|
||||
@@ -43,7 +46,7 @@ impl Drop for LoopDevice {
|
||||
.arg("-d")
|
||||
.arg(&self.path)
|
||||
.spawn()
|
||||
.unwrap()
|
||||
.expect("Failed to spawn command to detach loop device")
|
||||
.wait()
|
||||
.ok();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use super::Filesystem;
|
||||
use crate::error::{Error, ErrorKind};
|
||||
use failure::Fail;
|
||||
use anyhow::anyhow;
|
||||
use log::{debug, warn};
|
||||
use nix::mount::{mount, umount, MsFlags};
|
||||
use std::marker::PhantomData;
|
||||
@@ -56,21 +55,25 @@ impl<'a> MountStack<'a> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn _umount(&mut self) -> Result<(), Error> {
|
||||
fn _umount(&mut self) -> anyhow::Result<()> {
|
||||
let mut result = Ok(());
|
||||
|
||||
while let Some(target) = self.targets.pop() {
|
||||
debug!("Unmounting {}", target.display());
|
||||
if let Err(e) = umount(&target) {
|
||||
warn!("Unable to umount {}: {}", target.display(), e);
|
||||
result = Err(Error::from(e.context(ErrorKind::UmountFailure)));
|
||||
result = Err(anyhow!(
|
||||
"Failed unmounting filesystem: {}, {}",
|
||||
target.display(),
|
||||
e
|
||||
));
|
||||
};
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
pub fn umount(mut self) -> Result<(), Error> {
|
||||
pub fn umount(mut self) -> anyhow::Result<()> {
|
||||
self._umount()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use crate::error::{Error, ErrorKind};
|
||||
use anyhow::Context;
|
||||
use byte_unit::Byte;
|
||||
use failure::ResultExt;
|
||||
use std::{fmt, fs};
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -27,16 +26,16 @@ fn trimmed(source: String) -> String {
|
||||
String::from(source.trim_end())
|
||||
}
|
||||
|
||||
pub fn get_storage_devices(allow_non_removable: bool) -> Result<Vec<Device>, Error> {
|
||||
pub fn get_storage_devices(allow_non_removable: bool) -> anyhow::Result<Vec<Device>> {
|
||||
let mut result = Vec::new();
|
||||
|
||||
for entry in fs::read_dir("/sys/block").context(ErrorKind::StorageDevicesQuery)? {
|
||||
let entry = entry.context(ErrorKind::StorageDevicesQuery)?;
|
||||
for entry in fs::read_dir("/sys/block").context("Error querying storage devices")? {
|
||||
let entry = entry.context("Error querying storage devices")?;
|
||||
|
||||
let removable = allow_non_removable
|
||||
|| fs::read_to_string(entry.path().join("removable"))
|
||||
.map(|v| v == "1\n")
|
||||
.context(ErrorKind::StorageDevicesQuery)?;
|
||||
.context("Error querying storage devices")?;
|
||||
|
||||
if !removable {
|
||||
continue;
|
||||
@@ -44,7 +43,7 @@ pub fn get_storage_devices(allow_non_removable: bool) -> Result<Vec<Device>, Err
|
||||
|
||||
let model = fs::read_to_string(entry.path().join("device/model"))
|
||||
.map(trimmed)
|
||||
.context(ErrorKind::StorageDevicesQuery)?;
|
||||
.context("Error querying storage devices")?;
|
||||
|
||||
if model == "CD-ROM" {
|
||||
continue;
|
||||
@@ -54,19 +53,19 @@ pub fn get_storage_devices(allow_non_removable: bool) -> Result<Vec<Device>, Err
|
||||
name: entry
|
||||
.path()
|
||||
.file_name()
|
||||
.unwrap()
|
||||
.expect("Could not get file name for dir entry /sys/block")
|
||||
.to_string_lossy()
|
||||
.into_owned(),
|
||||
model,
|
||||
vendor: fs::read_to_string(entry.path().join("device/vendor"))
|
||||
.map(trimmed)
|
||||
.context(ErrorKind::StorageDevicesQuery)?,
|
||||
.context("Error querying storage devices")?,
|
||||
size: Byte::from_bytes(
|
||||
fs::read_to_string(entry.path().join("size"))
|
||||
.context(ErrorKind::StorageDevicesQuery)?
|
||||
.context("Error querying storage devices")?
|
||||
.trim()
|
||||
.parse::<u128>()
|
||||
.unwrap()
|
||||
.context("Could not parse block size to unsigned integer (u128)")?
|
||||
* 512,
|
||||
),
|
||||
})
|
||||
@@ -81,7 +80,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn sanity() {
|
||||
let devices = get_storage_devices(false).unwrap();
|
||||
let devices = get_storage_devices(false).expect("No devices");
|
||||
println!("{:?}", devices);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use super::markers::{BlockDevice, Origin};
|
||||
use super::partition::Partition;
|
||||
use crate::error::{Error, ErrorKind};
|
||||
use failure::ResultExt;
|
||||
use anyhow::{anyhow, Context};
|
||||
use log::debug;
|
||||
use std::fs::read_to_string;
|
||||
use std::marker::PhantomData;
|
||||
@@ -15,14 +14,16 @@ pub struct StorageDevice<'a> {
|
||||
}
|
||||
|
||||
impl<'a> StorageDevice<'a> {
|
||||
pub fn from_path(path: &'a Path, allow_non_removable: bool) -> Result<Self, Error> {
|
||||
pub fn from_path(path: &'a Path, allow_non_removable: bool) -> anyhow::Result<Self> {
|
||||
debug!("path: {:?}", path);
|
||||
let path = path.canonicalize().context(ErrorKind::DeviceQuery)?;
|
||||
let path = path
|
||||
.canonicalize()
|
||||
.context("Error querying information about the block device")?;
|
||||
let device_name = path
|
||||
.file_name()
|
||||
.and_then(|s| s.to_str())
|
||||
.map(String::from)
|
||||
.ok_or_else(|| Error::from(ErrorKind::InvalidDeviceName))?;
|
||||
.ok_or_else(|| anyhow!("Invalid device name: {}", path.display()))?;
|
||||
|
||||
debug!("real path: {:?}, device name: {:?}", path, device_name);
|
||||
|
||||
@@ -35,7 +36,10 @@ impl<'a> StorageDevice<'a> {
|
||||
// If we only allow removable/loop devices, and the device is neither removable or a loop
|
||||
// device then throw a DangerousDevice error
|
||||
if !(allow_non_removable || _self.is_removable_device()? || _self.is_loop_device()) {
|
||||
return Err(ErrorKind::DangerousDevice.into());
|
||||
return Err(anyhow!(
|
||||
"The given block device is neither removable nor a loop device: {}",
|
||||
_self.name
|
||||
));
|
||||
}
|
||||
|
||||
Ok(_self)
|
||||
@@ -47,12 +51,13 @@ impl<'a> StorageDevice<'a> {
|
||||
path
|
||||
}
|
||||
|
||||
fn is_removable_device(&self) -> Result<bool, Error> {
|
||||
fn is_removable_device(&self) -> anyhow::Result<bool> {
|
||||
let mut path = self.sys_path();
|
||||
path.push("removable");
|
||||
|
||||
debug!("Reading: {:?}", path);
|
||||
let result = read_to_string(&path).context(ErrorKind::DeviceQuery)?;
|
||||
let result =
|
||||
read_to_string(&path).context("Error querying information about the block device")?;
|
||||
debug!("{:?} -> {}", path, result);
|
||||
|
||||
Ok(result == "1\n")
|
||||
@@ -64,8 +69,15 @@ impl<'a> StorageDevice<'a> {
|
||||
path.exists()
|
||||
}
|
||||
|
||||
pub fn get_partition(&self, index: u8) -> Result<Partition, Error> {
|
||||
let name = if self.name.chars().rev().next().unwrap().is_digit(10) {
|
||||
pub fn get_partition(&self, index: u8) -> anyhow::Result<Partition> {
|
||||
let name = if self
|
||||
.name
|
||||
.chars()
|
||||
.rev()
|
||||
.next()
|
||||
.expect("Storage device name is empty")
|
||||
.is_digit(10)
|
||||
{
|
||||
format!("{}p{}", self.name, index)
|
||||
} else {
|
||||
format!("{}{}", self.name, index)
|
||||
@@ -75,7 +87,7 @@ impl<'a> StorageDevice<'a> {
|
||||
|
||||
debug!("Partition {} for {} is in {:?}", index, self.name, path);
|
||||
if !path.exists() {
|
||||
return Err(ErrorKind::NoSuchPartition(index).into());
|
||||
return Err(anyhow!("Partition {} does not exist", index));
|
||||
}
|
||||
Ok(Partition::new::<Self>(path))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user