shared: add better visibility into IO errors
parent
9d69515d19
commit
981f7e8701
|
@ -1,7 +1,7 @@
|
|||
use crate::Error;
|
||||
use colored::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use shared::{ensure_dirs_exist, Cidr, IoErrorContext, Peer, CLIENT_DATA_PATH};
|
||||
use shared::{ensure_dirs_exist, Cidr, IoErrorContext, Peer, WrappedIoError, CLIENT_DATA_PATH};
|
||||
use std::{
|
||||
fs::{File, OpenOptions},
|
||||
io::{Read, Seek, SeekFrom, Write},
|
||||
|
@ -23,7 +23,10 @@ pub enum Contents {
|
|||
}
|
||||
|
||||
impl DataStore {
|
||||
pub(self) fn open_with_path<P: AsRef<Path>>(path: P, create: bool) -> Result<Self, Error> {
|
||||
pub(self) fn open_with_path<P: AsRef<Path>>(
|
||||
path: P,
|
||||
create: bool,
|
||||
) -> Result<Self, WrappedIoError> {
|
||||
let path = path.as_ref();
|
||||
let mut file = OpenOptions::new()
|
||||
.read(true)
|
||||
|
@ -32,7 +35,7 @@ impl DataStore {
|
|||
.open(path)
|
||||
.with_path(path)?;
|
||||
|
||||
if shared::chmod(&file, 0o600)? {
|
||||
if shared::chmod(&file, 0o600).with_path(path)? {
|
||||
println!(
|
||||
"{} updated permissions for {} to 0600.",
|
||||
"[!]".yellow(),
|
||||
|
@ -56,16 +59,16 @@ impl DataStore {
|
|||
.with_extension("json")
|
||||
}
|
||||
|
||||
fn _open(interface: &InterfaceName, create: bool) -> Result<Self, Error> {
|
||||
fn _open(interface: &InterfaceName, create: bool) -> Result<Self, WrappedIoError> {
|
||||
ensure_dirs_exist(&[*CLIENT_DATA_PATH])?;
|
||||
Self::open_with_path(Self::get_path(interface), create)
|
||||
}
|
||||
|
||||
pub fn open(interface: &InterfaceName) -> Result<Self, Error> {
|
||||
pub fn open(interface: &InterfaceName) -> Result<Self, WrappedIoError> {
|
||||
Self::_open(interface, false)
|
||||
}
|
||||
|
||||
pub fn open_or_create(interface: &InterfaceName) -> Result<Self, Error> {
|
||||
pub fn open_or_create(interface: &InterfaceName) -> Result<Self, WrappedIoError> {
|
||||
Self::_open(interface, true)
|
||||
}
|
||||
|
||||
|
|
|
@ -400,7 +400,7 @@ fn fetch(
|
|||
let mut store = DataStore::open_or_create(&interface)?;
|
||||
let State { peers, cidrs } = Api::new(&config.server).http("GET", "/user/state")?;
|
||||
|
||||
let device_info = DeviceInfo::get_by_name(&interface)?;
|
||||
let device_info = DeviceInfo::get_by_name(&interface).with_str(interface.as_str_lossy())?;
|
||||
let interface_public_key = device_info
|
||||
.public_key
|
||||
.as_ref()
|
||||
|
@ -716,7 +716,12 @@ fn show(short: bool, tree: bool, interface: Option<Interface>) -> Result<(), Err
|
|||
|
||||
let devices = interfaces.into_iter().filter_map(|name| {
|
||||
DataStore::open(&name)
|
||||
.and_then(|store| Ok((DeviceInfo::get_by_name(&name)?, store)))
|
||||
.and_then(|store| {
|
||||
Ok((
|
||||
DeviceInfo::get_by_name(&name).with_str(name.as_str_lossy())?,
|
||||
store,
|
||||
))
|
||||
})
|
||||
.ok()
|
||||
});
|
||||
for (mut device_info, store) in devices {
|
||||
|
|
|
@ -31,22 +31,22 @@ pub type Error = Box<dyn std::error::Error>;
|
|||
pub static WG_MANAGE_DIR: &str = "/etc/innernet";
|
||||
pub static WG_DIR: &str = "/etc/wireguard";
|
||||
|
||||
pub fn ensure_dirs_exist(dirs: &[&Path]) -> Result<(), Error> {
|
||||
pub fn ensure_dirs_exist(dirs: &[&Path]) -> Result<(), WrappedIoError> {
|
||||
for dir in dirs {
|
||||
match fs::create_dir(dir) {
|
||||
match fs::create_dir(dir).with_path(dir) {
|
||||
Err(e) if e.kind() != io::ErrorKind::AlreadyExists => {
|
||||
return Err(e.into());
|
||||
},
|
||||
}
|
||||
_ => {
|
||||
let target_file = File::open(dir).with_path(dir)?;
|
||||
if chmod(&target_file, 0o700)? {
|
||||
if chmod(&target_file, 0o700).with_path(dir)? {
|
||||
println!(
|
||||
"{} updated permissions for {} to 0700.",
|
||||
"[!]".yellow(),
|
||||
dir.display()
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -55,7 +55,7 @@ pub fn ensure_dirs_exist(dirs: &[&Path]) -> Result<(), Error> {
|
|||
/// Updates the permissions of a file or directory. Returns `Ok(true)` if
|
||||
/// permissions had to be changed, `Ok(false)` if permissions were already
|
||||
/// correct.
|
||||
pub fn chmod(file: &File, new_mode: u32) -> Result<bool, Error> {
|
||||
pub fn chmod(file: &File, new_mode: u32) -> Result<bool, io::Error> {
|
||||
let metadata = file.metadata()?;
|
||||
let mut permissions = metadata.permissions();
|
||||
let mode = permissions.mode() & 0o777;
|
||||
|
|
|
@ -73,7 +73,7 @@ impl FromStr for Endpoint {
|
|||
let port = port.parse().map_err(|_| "couldn't parse port")?;
|
||||
let host = Host::parse(host).map_err(|_| "couldn't parse host")?;
|
||||
Ok(Endpoint { host, port })
|
||||
},
|
||||
}
|
||||
_ => Err("couldn't parse in form of 'host:port'"),
|
||||
}
|
||||
}
|
||||
|
@ -606,6 +606,14 @@ impl std::fmt::Display for WrappedIoError {
|
|||
}
|
||||
}
|
||||
|
||||
impl Deref for WrappedIoError {
|
||||
type Target = std::io::Error;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.io_error
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for WrappedIoError {}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -252,6 +252,7 @@ impl DeviceInfo {
|
|||
if backends::kernel::exists() {
|
||||
backends::kernel::get_by_name(name)
|
||||
} else {
|
||||
println!("kernel module not detected. falling back to userspace backend.");
|
||||
backends::userspace::get_by_name(name)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue