Migrate ALMA to anyhow (#54)

This commit is contained in:
James McMurray
2020-05-31 07:38:20 +02:00
committed by GitHub
parent c8b151fe5f
commit 7152901820
18 changed files with 448 additions and 626 deletions

View File

@@ -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)
}

View File

@@ -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 })
}

View File

@@ -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();
}

View File

@@ -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()
}
}

View File

@@ -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);
}
}

View File

@@ -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))
}