From 981f7e870106a80370a055c3059c631b9013f233 Mon Sep 17 00:00:00 2001 From: Jake McGinty Date: Sun, 9 May 2021 21:34:11 +0900 Subject: [PATCH] shared: add better visibility into IO errors --- client/src/data_store.rs | 15 +++++++++------ client/src/main.rs | 9 +++++++-- shared/src/lib.rs | 12 ++++++------ shared/src/types.rs | 10 +++++++++- wgctrl-rs/src/device.rs | 1 + 5 files changed, 32 insertions(+), 15 deletions(-) diff --git a/client/src/data_store.rs b/client/src/data_store.rs index dc59b06..d5a269e 100644 --- a/client/src/data_store.rs +++ b/client/src/data_store.rs @@ -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>(path: P, create: bool) -> Result { + pub(self) fn open_with_path>( + path: P, + create: bool, + ) -> Result { 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 { + fn _open(interface: &InterfaceName, create: bool) -> Result { ensure_dirs_exist(&[*CLIENT_DATA_PATH])?; Self::open_with_path(Self::get_path(interface), create) } - pub fn open(interface: &InterfaceName) -> Result { + pub fn open(interface: &InterfaceName) -> Result { Self::_open(interface, false) } - pub fn open_or_create(interface: &InterfaceName) -> Result { + pub fn open_or_create(interface: &InterfaceName) -> Result { Self::_open(interface, true) } diff --git a/client/src/main.rs b/client/src/main.rs index 360ad63..723ef6e 100644 --- a/client/src/main.rs +++ b/client/src/main.rs @@ -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) -> 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 { diff --git a/shared/src/lib.rs b/shared/src/lib.rs index cc02908..78d3c20 100644 --- a/shared/src/lib.rs +++ b/shared/src/lib.rs @@ -31,22 +31,22 @@ pub type Error = Box; 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 { +pub fn chmod(file: &File, new_mode: u32) -> Result { let metadata = file.metadata()?; let mut permissions = metadata.permissions(); let mode = permissions.mode() & 0o777; diff --git a/shared/src/types.rs b/shared/src/types.rs index f3fb01f..84ac6c1 100644 --- a/shared/src/types.rs +++ b/shared/src/types.rs @@ -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)] diff --git a/wgctrl-rs/src/device.rs b/wgctrl-rs/src/device.rs index 1f53611..674c1ee 100644 --- a/wgctrl-rs/src/device.rs +++ b/wgctrl-rs/src/device.rs @@ -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) } }