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},
};
use std::{fs, io::prelude::*};
use sysinfo::{DiskExt, SystemExt};
use sysinfo::{Disk, DiskExt, SystemExt};
use devices::{Device, DEVICESFILE};
use storages::{physical_drive_partition::*, Storage, StorageExt, StorageType, STORAGESFILE};
@ -75,6 +75,8 @@ enum StorageCommands {
},
/// List all storages.
List {},
/// Add new device-specific name to existing storage.
Bind { storage: String },
}
mod devices;
@ -89,7 +91,8 @@ fn main() -> Result<()> {
.init();
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");
trace!("Config dir: {:?}", config_dir);
@ -214,6 +217,28 @@ fn main() -> Result<()> {
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 {} => {
println!("{}", &config_dir.display());
@ -317,7 +342,23 @@ fn select_physical_storage(
for disk in sys_disks.disks() {
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()
.iter()
.enumerate()
@ -347,25 +388,13 @@ fn select_physical_storage(
let disk = inquire::Select::new("Select drive:", available_disks).prompt()?;
let disk_num: usize = disk.split(':').next().unwrap().parse().unwrap();
trace!("disk_num: {}", disk_num);
let (_, disk) = sys_disks
let disk = sysinfo
.disks()
.iter()
.enumerate()
.find(|(i, _)| i == &disk_num)
.unwrap();
.nth(disk_num)
.context("no disk matched with selected one.")?;
trace!("selected disk: {:?}", disk);
// 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)
Ok(disk)
}
/// Get `Vec<Storage>` from devices.yml([DEVICESFILE]).

View file

@ -27,11 +27,20 @@ pub enum 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 {
Self::PhysicalStorage(s) => s.name(),
}
}
}
impl fmt::Display for Storage {

View file

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