new: storage bind

This commit is contained in:
qwjyh 2023-08-29 21:33:46 +09:00
parent ae9cd0ee4c
commit d7e7665739
3 changed files with 76 additions and 40 deletions

View file

@ -27,7 +27,7 @@ use std::{
fs::{File, OpenOptions}, fs::{File, OpenOptions},
}; };
use std::{fs, io::prelude::*}; use std::{fs, io::prelude::*};
use sysinfo::{DiskExt, SystemExt}; use sysinfo::{Disk, DiskExt, SystemExt};
use devices::{Device, DEVICESFILE}; use devices::{Device, DEVICESFILE};
use storages::{physical_drive_partition::*, Storage, StorageExt, StorageType, STORAGESFILE}; use storages::{physical_drive_partition::*, Storage, StorageExt, StorageType, STORAGESFILE};
@ -75,6 +75,8 @@ enum StorageCommands {
}, },
/// List all storages. /// List all storages.
List {}, List {},
/// Add new device-specific name to existing storage.
Bind { storage: String },
} }
mod devices; mod devices;
@ -89,7 +91,8 @@ fn main() -> Result<()> {
.init(); .init();
trace!("Start logging..."); trace!("Start logging...");
let mut config_dir = dirs::config_local_dir().context("Failed to get config dir.")?; let mut config_dir: std::path::PathBuf =
dirs::config_local_dir().context("Failed to get config dir.")?;
config_dir.push("xdbm"); config_dir.push("xdbm");
trace!("Config dir: {:?}", config_dir); trace!("Config dir: {:?}", config_dir);
@ -214,6 +217,28 @@ fn main() -> Result<()> {
println!("{}", storage); println!("{}", storage);
} }
} }
StorageCommands::Bind {
storage: storage_name,
} => {
// get storages
let mut storages: Vec<Storage> = get_storages(&config_dir)?;
{
// find matching storage
let storage = &mut storages
.iter_mut()
.find(|s| s.name() == &storage_name)
.context(format!("No storage has name {}", storage_name))?;
// get disk from sysinfo
let mut sysinfo = sysinfo::System::new_all();
sysinfo.refresh_disks();
let disk = select_sysinfo_disk(&sysinfo)?;
// add to storages
storage.add_alias(disk, &config_dir)?;
trace!("storage: {}", storage);
}
trace!("bound new system name to the storage");
trace!("storages: {:#?}", storages);
}
}, },
Commands::Path {} => { Commands::Path {} => {
println!("{}", &config_dir.display()); println!("{}", &config_dir.display());
@ -317,7 +342,23 @@ fn select_physical_storage(
for disk in sys_disks.disks() { for disk in sys_disks.disks() {
trace!("{:?}", disk) trace!("{:?}", disk)
} }
let available_disks = sys_disks let disk = select_sysinfo_disk(&sys_disks)?;
// name the disk
let mut disk_name = String::new();
trace!("{}", disk_name);
loop {
disk_name = Text::new("Name for the disk:").prompt()?;
if storages.iter().all(|s| s.name() != &disk_name) {
break;
}
println!("The name {} is already used.", disk_name);
}
trace!("selected name: {}", disk_name);
PhysicalDrivePartition::try_from_sysinfo_disk(&disk, disk_name, device)
}
fn select_sysinfo_disk(sysinfo: &sysinfo::System) -> Result<&Disk> {
let available_disks = sysinfo
.disks() .disks()
.iter() .iter()
.enumerate() .enumerate()
@ -347,25 +388,13 @@ fn select_physical_storage(
let disk = inquire::Select::new("Select drive:", available_disks).prompt()?; let disk = inquire::Select::new("Select drive:", available_disks).prompt()?;
let disk_num: usize = disk.split(':').next().unwrap().parse().unwrap(); let disk_num: usize = disk.split(':').next().unwrap().parse().unwrap();
trace!("disk_num: {}", disk_num); trace!("disk_num: {}", disk_num);
let (_, disk) = sys_disks let disk = sysinfo
.disks() .disks()
.iter() .iter()
.enumerate() .nth(disk_num)
.find(|(i, _)| i == &disk_num) .context("no disk matched with selected one.")?;
.unwrap();
trace!("selected disk: {:?}", disk); trace!("selected disk: {:?}", disk);
// name the disk Ok(disk)
let mut disk_name = String::new();
trace!("{}", disk_name);
loop {
disk_name = Text::new("Name for the disk:").prompt()?;
if storages.iter().all(|s| s.name() != &disk_name) {
break;
}
println!("The name {} is already used.", disk_name);
}
trace!("selected name: {}", disk_name);
PhysicalDrivePartition::try_from_sysinfo_disk(disk, disk_name, device)
} }
/// Get `Vec<Storage>` from devices.yml([DEVICESFILE]). /// Get `Vec<Storage>` from devices.yml([DEVICESFILE]).

View file

@ -27,11 +27,20 @@ pub enum Storage {
} }
impl Storage { impl Storage {
pub fn name(&self) -> &String { pub fn add_alias(&mut self, disk: &sysinfo::Disk, config_dir: &std::path::PathBuf) -> anyhow::Result<()> {
match self {
Self::PhysicalStorage(s) => s.add_alias(disk, config_dir),
}
}
}
impl StorageExt for Storage {
fn name(&self) -> &String {
match self { match self {
Self::PhysicalStorage(s) => s.name(), Self::PhysicalStorage(s) => s.name(),
} }
} }
} }
impl fmt::Display for Storage { impl fmt::Display for Storage {

View file

@ -1,8 +1,8 @@
//! Manipulate partition of physical drive (both removable and unremovable). //! Manipulate partition of physical drive (both removable and unremovable).
use crate::devices::Device; use crate::{devices::Device, get_device};
use crate::storages::StorageExt; use crate::storages::StorageExt;
use anyhow::{Context, Result}; use anyhow::{anyhow, Context, Result};
use byte_unit::Byte; use byte_unit::Byte;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{ use std::{
@ -47,28 +47,25 @@ impl PhysicalDrivePartition {
}) })
} }
fn add_alias( pub fn add_alias(
self, &mut self,
disk: sysinfo::Disk, disk: &sysinfo::Disk,
device: Device, config_dir: &std::path::PathBuf
) -> Result<PhysicalDrivePartition, String> { ) -> Result<()> {
let device = get_device(&config_dir)?;
let alias = match disk.name().to_str() { let alias = match disk.name().to_str() {
Some(s) => s.to_string(), Some(s) => s.to_string(),
None => return Err("Failed to convert storage name to valid str.".to_string()), None => return Err(anyhow!("Failed to convert storage name to valid str.")),
}; };
let mut aliases = self.system_names; let aliases = &mut self.system_names;
let _ = match aliases.insert(device.name(), alias) { trace!("aliases: {:?}", aliases);
Some(v) => v, match aliases.insert(device.name(), alias) {
None => return Err("Failed to insert alias".to_string()), Some(v) => trace!("old val is: {}", v),
None => trace!("inserted new val"),
}; };
Ok(PhysicalDrivePartition { trace!("aliases: {:?}", aliases);
name: self.name, // self.system_names = aliases;
kind: self.kind, Ok(())
capacity: self.capacity,
fs: self.fs,
is_removable: self.is_removable,
system_names: aliases,
})
} }
} }
@ -76,6 +73,7 @@ impl StorageExt for PhysicalDrivePartition {
fn name(&self) -> &String { fn name(&self) -> &String {
&self.name &self.name
} }
} }
impl fmt::Display for PhysicalDrivePartition { impl fmt::Display for PhysicalDrivePartition {