mirror of
https://github.com/philmmanjaro/alma.git
synced 2025-07-26 06:59:28 +02:00
Add a flag for non-removable devices (fix #24)
This commit is contained in:
parent
25cdc44c7c
commit
750653c222
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -13,6 +13,7 @@ name = "alma"
|
||||
version = "0.9.0"
|
||||
dependencies = [
|
||||
"byte-unit 3.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"console 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dialoguer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -17,3 +17,4 @@ nix = "0.15.0"
|
||||
env_logger = "0.6.2"
|
||||
pretty_env_logger = "0.3.0"
|
||||
dialoguer = "0.4.0"
|
||||
console = "0.7.7"
|
||||
|
13
src/args.rs
13
src/args.rs
@ -60,9 +60,16 @@ pub struct CreateCommand {
|
||||
)]
|
||||
pub image: Option<Byte>,
|
||||
|
||||
/// Overwrite existing image files. Use with caution
|
||||
/// Overwrite existing image files. Use with caution!
|
||||
#[structopt(long = "overwrite")]
|
||||
pub overwrite: bool,
|
||||
|
||||
/// Allow installation on non-removable devices. Use with extreme caution!
|
||||
///
|
||||
/// If no device is specified in the command line, the device selection menu will
|
||||
/// show non-removable devices
|
||||
#[structopt(long = "allow-non-removable")]
|
||||
pub allow_non_removable: bool,
|
||||
}
|
||||
|
||||
#[derive(StructOpt)]
|
||||
@ -71,6 +78,10 @@ pub struct ChrootCommand {
|
||||
#[structopt(parse(from_os_str))]
|
||||
pub block_device: PathBuf,
|
||||
|
||||
/// Allow installation on non-removable devices. Use with extreme caution!
|
||||
#[structopt(long = "allow-non-removable")]
|
||||
pub allow_non_removable: bool,
|
||||
|
||||
/// Optional command to run
|
||||
#[structopt()]
|
||||
pub command: Vec<String>,
|
||||
|
@ -92,8 +92,8 @@ pub enum ErrorKind {
|
||||
#[fail(display = "Error setting up a loop device: {}", _0)]
|
||||
Losetup(String),
|
||||
|
||||
#[fail(display = "Error querying removeable devices")]
|
||||
RemoveableDevicesQuery,
|
||||
#[fail(display = "Error querying storage devices")]
|
||||
StorageDevicesQuery,
|
||||
|
||||
#[fail(display = "There are no removable devices")]
|
||||
NoRemovableDevices,
|
||||
|
36
src/main.rs
36
src/main.rs
@ -12,6 +12,7 @@ use crate::process::CommandExt;
|
||||
use crate::storage::*;
|
||||
use crate::tool::Tool;
|
||||
use byte_unit::Byte;
|
||||
use console::style;
|
||||
use dialoguer::{theme::ColorfulTheme, Select};
|
||||
use failure::{Fail, ResultExt};
|
||||
use log::{debug, error, info, log_enabled, Level, LevelFilter};
|
||||
@ -91,13 +92,22 @@ fn create_image(path: &Path, size: Byte, overwrite: bool) -> Result<LoopDevice,
|
||||
LoopDevice::create(path)
|
||||
}
|
||||
|
||||
fn select_block_device() -> Result<PathBuf, Error> {
|
||||
let devices = get_removable_devices()?;
|
||||
fn select_block_device(allow_non_removable: bool) -> Result<PathBuf, Error> {
|
||||
let devices = get_storage_devices(allow_non_removable)?;
|
||||
|
||||
if devices.is_empty() {
|
||||
Err(ErrorKind::NoRemovableDevices)?
|
||||
}
|
||||
|
||||
if allow_non_removable {
|
||||
println!(
|
||||
"{}\n",
|
||||
style("Showing non-removable devices. Make sure you select the correct device.")
|
||||
.red()
|
||||
.bold()
|
||||
);
|
||||
}
|
||||
|
||||
let selection = Select::with_theme(&ColorfulTheme::default())
|
||||
.with_prompt("Select a removable device")
|
||||
.default(0)
|
||||
@ -132,7 +142,7 @@ fn create(command: CreateCommand) -> Result<(), Error> {
|
||||
let storage_device_path = if let Some(path) = command.path {
|
||||
path
|
||||
} else {
|
||||
select_block_device()?
|
||||
select_block_device(command.allow_non_removable)?
|
||||
};
|
||||
|
||||
let image_loop = if let Some(size) = command.image {
|
||||
@ -149,6 +159,7 @@ fn create(command: CreateCommand) -> Result<(), Error> {
|
||||
loop_dev.path()
|
||||
})
|
||||
.unwrap_or(&storage_device_path),
|
||||
command.allow_non_removable,
|
||||
)?;
|
||||
|
||||
let mount_point = tempdir().context(ErrorKind::TmpDirError)?;
|
||||
@ -373,13 +384,18 @@ fn chroot(command: ChrootCommand) -> Result<(), Error> {
|
||||
let mut cryptsetup;
|
||||
|
||||
let mut loop_device: Option<LoopDevice>;
|
||||
let storage_device = match storage::StorageDevice::from_path(&command.block_device) {
|
||||
Ok(b) => b,
|
||||
Err(_) => {
|
||||
loop_device = Some(LoopDevice::create(&command.block_device)?);
|
||||
storage::StorageDevice::from_path(loop_device.as_ref().unwrap().path())?
|
||||
}
|
||||
};
|
||||
let storage_device =
|
||||
match storage::StorageDevice::from_path(&command.block_device, command.allow_non_removable)
|
||||
{
|
||||
Ok(b) => b,
|
||||
Err(_) => {
|
||||
loop_device = Some(LoopDevice::create(&command.block_device)?);
|
||||
storage::StorageDevice::from_path(
|
||||
loop_device.as_ref().unwrap().path(),
|
||||
command.allow_non_removable,
|
||||
)?
|
||||
}
|
||||
};
|
||||
let mount_point = tempdir().context(ErrorKind::TmpDirError)?;
|
||||
|
||||
let boot_partition = storage_device.get_partition(BOOT_PARTITION_INDEX)?;
|
||||
|
@ -12,5 +12,5 @@ pub use filesystem::{Filesystem, FilesystemType};
|
||||
pub use loop_device::LoopDevice;
|
||||
pub use markers::BlockDevice;
|
||||
pub use mount_stack::MountStack;
|
||||
pub use removeable_devices::get_removable_devices;
|
||||
pub use removeable_devices::get_storage_devices;
|
||||
pub use storage_device::StorageDevice;
|
||||
|
@ -27,22 +27,24 @@ fn trimmed(source: String) -> String {
|
||||
String::from(source.trim_end())
|
||||
}
|
||||
|
||||
pub fn get_removable_devices() -> Result<Vec<Device>, Error> {
|
||||
pub fn get_storage_devices(allow_non_removable: bool) -> Result<Vec<Device>, Error> {
|
||||
let mut result = Vec::new();
|
||||
|
||||
for entry in fs::read_dir("/sys/block").context(ErrorKind::RemoveableDevicesQuery)? {
|
||||
let entry = entry.context(ErrorKind::RemoveableDevicesQuery)?;
|
||||
for entry in fs::read_dir("/sys/block").context(ErrorKind::StorageDevicesQuery)? {
|
||||
let entry = entry.context(ErrorKind::StorageDevicesQuery)?;
|
||||
|
||||
let removable = fs::read_to_string(entry.path().join("removable"))
|
||||
.context(ErrorKind::RemoveableDevicesQuery)?;
|
||||
let removable = allow_non_removable
|
||||
|| fs::read_to_string(entry.path().join("removable"))
|
||||
.map(|v| v == "1\n")
|
||||
.context(ErrorKind::StorageDevicesQuery)?;
|
||||
|
||||
if removable != "1\n" {
|
||||
if !removable {
|
||||
continue;
|
||||
}
|
||||
|
||||
let model = fs::read_to_string(entry.path().join("device/model"))
|
||||
.map(trimmed)
|
||||
.context(ErrorKind::RemoveableDevicesQuery)?;
|
||||
.context(ErrorKind::StorageDevicesQuery)?;
|
||||
|
||||
if model == "CD-ROM" {
|
||||
continue;
|
||||
@ -58,10 +60,10 @@ pub fn get_removable_devices() -> Result<Vec<Device>, Error> {
|
||||
model,
|
||||
vendor: fs::read_to_string(entry.path().join("device/vendor"))
|
||||
.map(trimmed)
|
||||
.context(ErrorKind::RemoveableDevicesQuery)?,
|
||||
.context(ErrorKind::StorageDevicesQuery)?,
|
||||
size: Byte::from_bytes(
|
||||
fs::read_to_string(entry.path().join("size"))
|
||||
.context(ErrorKind::RemoveableDevicesQuery)?
|
||||
.context(ErrorKind::StorageDevicesQuery)?
|
||||
.trim()
|
||||
.parse::<u128>()
|
||||
.unwrap()
|
||||
|
@ -15,7 +15,7 @@ pub struct StorageDevice<'a> {
|
||||
}
|
||||
|
||||
impl<'a> StorageDevice<'a> {
|
||||
pub fn from_path(path: &'a Path) -> Result<Self, Error> {
|
||||
pub fn from_path(path: &'a Path, allow_non_removable: bool) -> Result<Self, Error> {
|
||||
debug!("path: {:?}", path);
|
||||
let path = path.canonicalize().context(ErrorKind::DeviceQuery)?;
|
||||
let device_name = path
|
||||
@ -31,7 +31,7 @@ impl<'a> StorageDevice<'a> {
|
||||
path,
|
||||
origin: PhantomData,
|
||||
};
|
||||
if !(_self.is_removable_device()? || _self.is_loop_device()) {
|
||||
if !allow_non_removable && (!(_self.is_removable_device()? || _self.is_loop_device())) {
|
||||
return Err(ErrorKind::DangerousDevice)?;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user