diff options
| author | Linus Färnstrand <linus@mullvad.net> | 2019-04-12 12:25:17 +0200 |
|---|---|---|
| committer | Linus Färnstrand <linus@mullvad.net> | 2019-04-12 12:25:17 +0200 |
| commit | 9ee8720d10217914ea15cd344ef2c3a4be71ca6b (patch) | |
| tree | 9cb18883695bc01b1159bcf0638c50899e14b4a7 | |
| parent | f720db702dfc5afae6210d2d0b42960702856c72 (diff) | |
| parent | cf3b0755b4fc526770b7f7c80bf5a0df85565774 (diff) | |
| download | mullvadvpn-9ee8720d10217914ea15cd344ef2c3a4be71ca6b.tar.xz mullvadvpn-9ee8720d10217914ea15cd344ef2c3a4be71ca6b.zip | |
Merge branch 'eliminate-error-chain-daemon'
| -rw-r--r-- | Cargo.lock | 1 | ||||
| -rw-r--r-- | mullvad-daemon/Cargo.toml | 1 | ||||
| -rw-r--r-- | mullvad-daemon/src/cli.rs | 9 | ||||
| -rw-r--r-- | mullvad-daemon/src/lib.rs | 188 | ||||
| -rw-r--r-- | mullvad-daemon/src/main.rs | 91 | ||||
| -rw-r--r-- | mullvad-daemon/src/management_interface.rs | 2 | ||||
| -rw-r--r-- | mullvad-daemon/src/system_service.rs | 45 |
7 files changed, 172 insertions, 165 deletions
diff --git a/Cargo.lock b/Cargo.lock index 3cfe9cbc90..615b812eac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1086,7 +1086,6 @@ dependencies = [ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "ctrlc 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "err-derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "fern 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "ipnetwork 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/mullvad-daemon/Cargo.toml b/mullvad-daemon/Cargo.toml index 5d252c1217..b50b97d96a 100644 --- a/mullvad-daemon/Cargo.toml +++ b/mullvad-daemon/Cargo.toml @@ -16,7 +16,6 @@ edition = "2018" [dependencies] chrono = { version = "0.4", features = ["serde"] } clap = "2.25" -error-chain = "0.12" err-derive = "0.1.5" fern = { version = "0.5", features = ["colored"] } futures = "0.1" diff --git a/mullvad-daemon/src/cli.rs b/mullvad-daemon/src/cli.rs index 722a176878..d39a80309e 100644 --- a/mullvad-daemon/src/cli.rs +++ b/mullvad-daemon/src/cli.rs @@ -11,7 +11,14 @@ pub struct Config { pub register_service: bool, } -pub fn get_config() -> Config { +pub fn get_config() -> &'static Config { + lazy_static::lazy_static! { + static ref CONFIG: Config = create_config(); + } + &*CONFIG +} + +pub fn create_config() -> Config { let app = create_app(); let matches = app.get_matches(); diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs index 8edd755c60..aab7f406f7 100644 --- a/mullvad-daemon/src/lib.rs +++ b/mullvad-daemon/src/lib.rs @@ -9,8 +9,6 @@ #![deny(rust_2018_idioms)] #[macro_use] -extern crate error_chain; -#[macro_use] extern crate serde; @@ -41,7 +39,7 @@ use mullvad_types::{ states::TargetState, version::{AppVersion, AppVersionInfo}, }; -use std::{mem, path::PathBuf, sync::mpsc, thread, time::Duration}; +use std::{io, mem, path::PathBuf, sync::mpsc, thread, time::Duration}; use talpid_core::{ mpsc::IntoSender, tunnel_state_machine::{self, TunnelCommand, TunnelParametersGenerator}, @@ -52,30 +50,43 @@ use talpid_types::{ ErrorExt, }; +pub type Result<T> = std::result::Result<T, Error>; -error_chain! { - errors { - NoCacheDir { - description("Unable to create cache directory") - } - DaemonIsAlreadyRunning { - description("Another instance of the daemon is already running") - } - UnsupportedTunnel { - description("Unsupported tunnel") - } - ManagementInterfaceError(msg: &'static str) { - description("Error in the management interface") - display("Management interface error: {}", msg) - } - NoKeyAvailable { - description("No wireguard private key available") - } - } - foreign_links { - AccountHistory(account_history::Error); - TunnelError(tunnel_state_machine::Error); - } +#[derive(err_derive::Error, Debug)] +pub enum Error { + #[error(display = "Another instance of the daemon is already running")] + DaemonIsAlreadyRunning, + + #[error(display = "Unable to initialize network event loop")] + InitIoEventLoop(#[error(cause)] io::Error), + + #[error(display = "Unable to create RPC client")] + InitRpcClient(#[error(cause)] mullvad_rpc::HttpError), + + #[error(display = "Unable to create am.i.mullvad client")] + InitHttpsClient(#[error(cause)] mullvad_rpc::rest::Error), + + #[error(display = "Unable to load settings")] + LoadSettings(#[error(cause)] settings::Error), + + #[error(display = "Unable to load account history with wireguard key cache")] + LoadAccountHistory(#[error(cause)] account_history::Error), + + /// Error in the management interface + #[error(display = "Unable to start management interface server")] + StartManagementInterface(#[error(cause)] talpid_ipc::Error), + + #[error(display = "Management interface server exited unexpectedly")] + ManagementInterfaceExited, + + #[error(display = "No wireguard private key available")] + NoKeyAvailable, + + #[error(display = "Account history problems")] + AccountHistory(#[error(cause)] account_history::Error), + + #[error(display = "Tunnel state machine error")] + TunnelError(#[error(cause)] tunnel_state_machine::Error), } type SyncUnboundedSender<T> = ::futures::sink::Wait<UnboundedSender<T>>; @@ -180,10 +191,9 @@ impl Daemon { cache_dir: PathBuf, version: String, ) -> Result<Self> { - ensure!( - !rpc_uniqueness_check::is_another_instance_running(), - ErrorKind::DaemonIsAlreadyRunning - ); + if rpc_uniqueness_check::is_another_instance_running() { + return Err(Error::DaemonIsAlreadyRunning); + } let ca_path = resource_dir.join(mullvad_paths::resources::API_CA_FILENAME); let mut rpc_manager = mullvad_rpc::MullvadRpcFactory::with_cache_dir(&cache_dir, &ca_path); @@ -196,9 +206,9 @@ impl Daemon { let remote = core.remote(); (rpc, https_handle, remote) }) - .chain_err(|| "Unable to initialize network event loop")?; - let rpc_handle = rpc_handle.chain_err(|| "Unable to create RPC client")?; - let https_handle = https_handle.chain_err(|| "Unable to create am.i.mullvad client")?; + .map_err(Error::InitIoEventLoop)?; + let rpc_handle = rpc_handle.map_err(Error::InitRpcClient)?; + let https_handle = https_handle.map_err(Error::InitHttpsClient)?; let (internal_event_tx, internal_event_rx) = mpsc::channel(); @@ -215,9 +225,9 @@ impl Daemon { &resource_dir, &cache_dir, ); - let settings = Settings::load().chain_err(|| "Unable to read settings")?; - let account_history = account_history::AccountHistory::new(&cache_dir) - .chain_err(|| "Unable to read wireguard key cache")?; + let settings = Settings::load().map_err(Error::LoadSettings)?; + let account_history = + account_history::AccountHistory::new(&cache_dir).map_err(Error::LoadAccountHistory)?; let tunnel_parameters_generator = MullvadTunnelParametersGenerator { tx: internal_event_tx.clone(), @@ -230,7 +240,8 @@ impl Daemon { resource_dir, cache_dir.clone(), IntoSender::from(internal_event_tx.clone()), - )?; + ) + .map_err(Error::TunnelError)?; // Attempt to download a fresh relay list relay_selector.update(); @@ -275,8 +286,8 @@ impl Daemon { fn start_management_interface_server( event_tx: IntoSender<ManagementCommand, InternalDaemonEvent>, ) -> Result<ManagementInterfaceServer> { - let server = ManagementInterfaceServer::start(event_tx) - .chain_err(|| ErrorKind::ManagementInterfaceError("Failed to start server"))?; + let server = + ManagementInterfaceServer::start(event_tx).map_err(Error::StartManagementInterface)?; info!( "Mullvad management interface listening on {}", server.socket_path() @@ -321,9 +332,7 @@ impl Daemon { } ManagementInterfaceEvent(event) => self.handle_management_interface_event(event), ManagementInterfaceExited => { - return Err( - ErrorKind::ManagementInterfaceError("Server exited unexpectedly").into(), - ); + return Err(Error::ManagementInterfaceExited); } TriggerShutdown => self.handle_trigger_shutdown_event(), } @@ -358,35 +367,39 @@ impl Daemon { tunnel_parameters_tx: &mpsc::Sender<TunnelParameters>, retry_attempt: u32, ) { - let result = self - .settings - .get_account_token() - .ok_or_else(|| Error::from("No account token configured")) - .map(|account_token| { - match self.settings.get_relay_settings() { - RelaySettings::CustomTunnelEndpoint(custom_relay) => { - self.last_generated_relay = None; - custom_relay - .to_tunnel_parameters(self.settings.get_tunnel_options().clone()) - .chain_err(|| "Custom tunnel endpoint could not be resolved") - } - RelaySettings::Normal(constraints) => self - .relay_selector - .get_tunnel_endpoint(&constraints, retry_attempt) - .chain_err(|| "No valid relay servers match the current settings") - .and_then(|(relay, endpoint)| { - self.last_generated_relay = Some(relay); - self.create_tunnel_parameters(endpoint, account_token) - }), + if let Some(account_token) = self.settings.get_account_token() { + if let Err(error_str) = match self.settings.get_relay_settings() { + RelaySettings::CustomTunnelEndpoint(custom_relay) => { + self.last_generated_relay = None; + custom_relay + .to_tunnel_parameters(self.settings.get_tunnel_options().clone()) + .map_err(|e| { + e.display_chain_with_msg("Custom tunnel endpoint could not be resolved") + }) } - .map(|tunnel_params| { - tunnel_parameters_tx - .send(tunnel_params) - .map_err(|_| Error::from("Tunnel parameters receiver stopped listening")) + RelaySettings::Normal(constraints) => self + .relay_selector + .get_tunnel_endpoint(&constraints, retry_attempt) + .map_err(|e| { + e.display_chain_with_msg( + "No valid relay servers match the current settings", + ) + }) + .and_then(|(relay, endpoint)| { + self.last_generated_relay = Some(relay); + self.create_tunnel_parameters(endpoint, account_token) + .map_err(|e| e.display_chain()) + }), + } + .and_then(|tunnel_params| { + tunnel_parameters_tx.send(tunnel_params).map_err(|e| { + e.display_chain_with_msg("Tunnel parameters receiver stopped listening") }) - }); - if let Err(e) = result { - error!("{}", e.display_chain()); + }) { + error!("{}", error_str); + } + } else { + error!("No account token configured"); } } @@ -410,9 +423,10 @@ impl Daemon { } => { let wg_data = self .account_history - .get(&account_token)? + .get(&account_token) + .map_err(Error::AccountHistory)? .and_then(|entry| entry.wireguard) - .ok_or(ErrorKind::NoKeyAvailable)?; + .ok_or(Error::NoKeyAvailable)?; let tunnel = wireguard::TunnelConfig { private_key: wg_data.private_key, addresses: vec![ @@ -592,7 +606,7 @@ impl Daemon { fn on_set_account(&mut self, tx: oneshot::Sender<()>, account_token: Option<String>) { let save_result = self.settings.set_account_token(account_token.clone()); - match save_result.chain_err(|| "Unable to save settings") { + match save_result { Ok(account_changed) => { Self::oneshot_send(tx, (), "set_account response"); if account_changed { @@ -613,7 +627,7 @@ impl Daemon { } } } - Err(e) => error!("{}", e.display_chain()), + Err(e) => error!("{}", e.display_chain_with_msg("Unable to save settings")), } } @@ -660,7 +674,7 @@ impl Daemon { fn on_update_relay_settings(&mut self, tx: oneshot::Sender<()>, update: RelaySettingsUpdate) { let save_result = self.settings.update_relay_settings(update); - match save_result.chain_err(|| "Unable to save settings") { + match save_result { Ok(settings_changed) => { Self::oneshot_send(tx, (), "update_relay_settings response"); if settings_changed { @@ -670,13 +684,13 @@ impl Daemon { self.reconnect_tunnel(); } } - Err(e) => error!("{}", e.display_chain()), + Err(e) => error!("{}", e.display_chain_with_msg("Unable to save settings")), } } fn on_set_allow_lan(&mut self, tx: oneshot::Sender<()>, allow_lan: bool) { let save_result = self.settings.set_allow_lan(allow_lan); - match save_result.chain_err(|| "Unable to save settings") { + match save_result { Ok(settings_changed) => { Self::oneshot_send(tx, (), "set_allow_lan response"); if settings_changed { @@ -685,7 +699,7 @@ impl Daemon { self.send_tunnel_command(TunnelCommand::AllowLan(allow_lan)); } } - Err(e) => error!("{}", e.display_chain()), + Err(e) => error!("{}", e.display_chain_with_msg("Unable to save settings")), } } @@ -697,7 +711,7 @@ impl Daemon { let save_result = self .settings .set_block_when_disconnected(block_when_disconnected); - match save_result.chain_err(|| "Unable to save settings") { + match save_result { Ok(settings_changed) => { Self::oneshot_send(tx, (), "set_block_when_disconnected response"); if settings_changed { @@ -708,13 +722,13 @@ impl Daemon { )); } } - Err(e) => error!("{}", e.display_chain()), + Err(e) => error!("{}", e.display_chain_with_msg("Unable to save settings")), } } fn on_set_auto_connect(&mut self, tx: oneshot::Sender<()>, auto_connect: bool) { let save_result = self.settings.set_auto_connect(auto_connect); - match save_result.chain_err(|| "Unable to save settings") { + match save_result { Ok(settings_changed) => { Self::oneshot_send(tx, (), "set auto-connect response"); if settings_changed { @@ -722,13 +736,13 @@ impl Daemon { .notify_settings(self.settings.clone()); } } - Err(e) => error!("{}", e.display_chain()), + Err(e) => error!("{}", e.display_chain_with_msg("Unable to save settings")), } } fn on_set_openvpn_mssfix(&mut self, tx: oneshot::Sender<()>, mssfix_arg: Option<u16>) { let save_result = self.settings.set_openvpn_mssfix(mssfix_arg); - match save_result.chain_err(|| "Unable to save settings") { + match save_result { Ok(settings_changed) => { Self::oneshot_send(tx, (), "set_openvpn_mssfix response"); if settings_changed { @@ -738,7 +752,7 @@ impl Daemon { self.reconnect_tunnel(); } } - Err(e) => error!("{}", e.display_chain()), + Err(e) => error!("{}", e.display_chain_with_msg("Unable to save settings")), } } @@ -795,7 +809,7 @@ impl Daemon { fn on_set_enable_ipv6(&mut self, tx: oneshot::Sender<()>, enable_ipv6: bool) { let save_result = self.settings.set_enable_ipv6(enable_ipv6); - match save_result.chain_err(|| "Unable to save settings") { + match save_result { Ok(settings_changed) => { Self::oneshot_send(tx, (), "set_enable_ipv6 response"); if settings_changed { @@ -805,13 +819,13 @@ impl Daemon { self.reconnect_tunnel(); } } - Err(e) => error!("{}", e.display_chain()), + Err(e) => error!("{}", e.display_chain_with_msg("Unable to save settings")), } } fn on_set_wireguard_mtu(&mut self, tx: oneshot::Sender<()>, mtu: Option<u16>) { let save_result = self.settings.set_wireguard_mtu(mtu); - match save_result.chain_err(|| "Unable to save settings") { + match save_result { Ok(settings_changed) => { Self::oneshot_send(tx, (), "set_wireguard_mtu response"); if settings_changed { @@ -821,7 +835,7 @@ impl Daemon { self.reconnect_tunnel(); } } - Err(e) => error!("{}", e.display_chain()), + Err(e) => error!("{}", e.display_chain_with_msg("Unable to save settings")), } } diff --git a/mullvad-daemon/src/main.rs b/mullvad-daemon/src/main.rs index bb9afb65ee..e9346405d9 100644 --- a/mullvad-daemon/src/main.rs +++ b/mullvad-daemon/src/main.rs @@ -8,14 +8,10 @@ #![deny(rust_2018_idioms)] -#[macro_use] -extern crate error_chain; - - -use error_chain::ChainedError; use log::{debug, error, info, warn}; use mullvad_daemon::Daemon; -use std::{thread, time::Duration}; +use std::{path::PathBuf, thread, time::Duration}; +use talpid_types::ErrorExt; mod cli; mod logging; @@ -26,44 +22,25 @@ mod version; const DAEMON_LOG_FILENAME: &str = "daemon.log"; -error_chain! { - errors { - LogError(msg: &'static str) { - description("Error setting up log") - display("Error setting up log: {}", msg) - } - } - links { - DaemonError(mullvad_daemon::Error, mullvad_daemon::ErrorKind); - } -} - fn main() { - let exit_code = match run() { + let config = cli::get_config(); + let log_dir = init_logging(config).unwrap_or_else(|error| { + eprintln!("{}", error); + std::process::exit(1) + }); + let exit_code = match run_platform(config, log_dir) { Ok(_) => 0, Err(error) => { - if let ErrorKind::LogError(_) = error.kind() { - eprintln!("{}", error.display_chain()); - } else { - error!("{}", error.display_chain()); - } + error!("{}", error); 1 } }; debug!("Process exiting with code {}", exit_code); - ::std::process::exit(exit_code); + std::process::exit(exit_code); } -fn run() -> Result<()> { - let config = cli::get_config(); - let log_dir = if config.log_to_file { - Some( - mullvad_paths::log_dir() - .chain_err(|| ErrorKind::LogError("Unable to get log directory"))?, - ) - } else { - None - }; +fn init_logging(config: &cli::Config) -> Result<Option<PathBuf>, String> { + let log_dir = get_log_dir(config)?; let log_file = log_dir.as_ref().map(|dir| dir.join(DAEMON_LOG_FILENAME)); logging::init_logger( @@ -71,65 +48,69 @@ fn run() -> Result<()> { log_file.as_ref(), config.log_stdout_timestamps, ) - .chain_err(|| ErrorKind::LogError("Unable to initialize logger"))?; + .map_err(|e| e.display_chain_with_msg("Unable to initialize logger"))?; log_panics::init(); log_version(); if let Some(ref log_dir) = log_dir { info!("Logging to {}", log_dir.display()); } + Ok(log_dir) +} - run_platform(&config) +fn get_log_dir(config: &cli::Config) -> Result<Option<PathBuf>, String> { + if config.log_to_file { + Ok(Some(mullvad_paths::log_dir().map_err(|e| { + e.display_chain_with_msg("Unable to get log directory") + })?)) + } else { + Ok(None) + } } #[cfg(windows)] -fn run_platform(config: &cli::Config) -> Result<()> { +fn run_platform(config: &cli::Config, log_dir: Option<PathBuf>) -> Result<(), String> { if config.run_as_service { system_service::run() } else { if config.register_service { - let install_result = - system_service::install_service().chain_err(|| "Unable to install the service"); + let install_result = system_service::install_service().map_err(|e| e.display_chain()); if install_result.is_ok() { println!("Installed the service."); } install_result } else { - run_standalone(config) + run_standalone(log_dir) } } } #[cfg(not(windows))] -fn run_platform(config: &cli::Config) -> Result<()> { - run_standalone(config) +fn run_platform(_config: &cli::Config, log_dir: Option<PathBuf>) -> Result<(), String> { + run_standalone(log_dir) } -fn run_standalone(config: &cli::Config) -> Result<()> { +fn run_standalone(log_dir: Option<PathBuf>) -> Result<(), String> { if !running_as_admin() { warn!("Running daemon as a non-administrator user, clients might refuse to connect"); } - let daemon = create_daemon(config)?; + let daemon = create_daemon(log_dir)?; let shutdown_handle = daemon.shutdown_handle(); shutdown::set_shutdown_signal_handler(move || shutdown_handle.shutdown()) - .chain_err(|| "Unable to attach shutdown signal handler")?; + .map_err(|e| e.display_chain())?; - daemon.run()?; + daemon.run().map_err(|e| e.display_chain())?; info!("Mullvad daemon is quitting"); thread::sleep(Duration::from_millis(500)); Ok(()) } -fn create_daemon(config: &cli::Config) -> Result<Daemon> { - let log_dir = if config.log_to_file { - Some(mullvad_paths::log_dir().chain_err(|| "Unable to get log directory")?) - } else { - None - }; +fn create_daemon(log_dir: Option<PathBuf>) -> Result<Daemon, String> { let resource_dir = mullvad_paths::get_resource_dir(); - let cache_dir = mullvad_paths::cache_dir().chain_err(|| "Unable to get cache dir")?; + let cache_dir = mullvad_paths::cache_dir() + .map_err(|e| e.display_chain_with_msg("Unable to get cache dir"))?; Daemon::start( log_dir, @@ -137,7 +118,7 @@ fn create_daemon(config: &cli::Config) -> Result<Daemon> { cache_dir, version::PRODUCT_VERSION.to_owned(), ) - .chain_err(|| "Unable to initialize daemon") + .map_err(|e| e.display_chain_with_msg("Unable to initialize daemon")) } fn log_version() { diff --git a/mullvad-daemon/src/management_interface.rs b/mullvad-daemon/src/management_interface.rs index 24bf2df391..cb313ed653 100644 --- a/mullvad-daemon/src/management_interface.rs +++ b/mullvad-daemon/src/management_interface.rs @@ -1,4 +1,3 @@ -use error_chain::ChainedError; use jsonrpc_core::{ futures::{ future, @@ -30,6 +29,7 @@ use talpid_ipc; use talpid_types::{ net::{openvpn, wireguard}, tunnel::TunnelStateTransition, + ErrorExt, }; use uuid; diff --git a/mullvad-daemon/src/system_service.rs b/mullvad-daemon/src/system_service.rs index c4b98d88fc..61bbb84981 100644 --- a/mullvad-daemon/src/system_service.rs +++ b/mullvad-daemon/src/system_service.rs @@ -1,5 +1,5 @@ use crate::cli; -use error_chain::ChainedError; +use mullvad_daemon::DaemonShutdownHandle; use std::{ env, ffi::OsString, @@ -10,6 +10,7 @@ use std::{ thread, time::Duration, }; +use talpid_types::ErrorExt; use windows_service::{ service::{ ServiceAccess, ServiceControl, ServiceControlAccept, ServiceDependency, @@ -21,19 +22,16 @@ use windows_service::{ service_manager::{ServiceManager, ServiceManagerAccess}, }; -use super::{Result, ResultExt}; -use mullvad_daemon::DaemonShutdownHandle; - static SERVICE_NAME: &'static str = "MullvadVPN"; static SERVICE_DISPLAY_NAME: &'static str = "Mullvad VPN Service"; static SERVICE_TYPE: ServiceType = ServiceType::OWN_PROCESS; -pub fn run() -> Result<()> { +pub fn run() -> Result<(), String> { // Start the service dispatcher. // This will block current thread until the service stopped and spawn `service_main` on a // background thread. service_dispatcher::start(SERVICE_NAME, service_main) - .chain_err(|| "Failed to start a service dispatcher") + .map_err(|e| e.display_chain_with_msg("Failed to start a service dispatcher")) } windows_service::define_windows_service!(service_main, handle_service_main); @@ -42,11 +40,11 @@ pub fn handle_service_main(_arguments: Vec<OsString>) { log::info!("Service started."); match run_service() { Ok(()) => log::info!("Service stopped."), - Err(error) => log::error!("{}", error.display_chain()), + Err(error) => log::error!("{}", error), }; } -fn run_service() -> Result<()> { +fn run_service() -> Result<(), String> { let (event_tx, event_rx) = mpsc::channel(); // Register service event handler @@ -65,14 +63,14 @@ fn run_service() -> Result<()> { } }; let status_handle = service_control_handler::register(SERVICE_NAME, event_handler) - .chain_err(|| "Failed to register a service control handler")?; + .map_err(|e| e.display_chain_with_msg("Failed to register a service control handler"))?; let mut persistent_service_status = PersistentServiceStatus::new(status_handle); persistent_service_status .set_pending_start(Duration::from_secs(1)) .unwrap(); - let config = cli::get_config(); - let result = crate::create_daemon(&config).and_then(|daemon| { + let log_dir = crate::get_log_dir(cli::get_config()).expect("Log dir should be available here"); + let result = crate::create_daemon(log_dir).and_then(|daemon| { let shutdown_handle = daemon.shutdown_handle(); // Register monitor that translates `ServiceControl` to Daemon events @@ -80,7 +78,7 @@ fn run_service() -> Result<()> { persistent_service_status.set_running().unwrap(); - Ok(daemon.run()?) + daemon.run().map_err(|e| e.display_chain()) }); let exit_code = match result { @@ -216,18 +214,27 @@ fn accepted_controls_by_state(state: ServiceState) -> ServiceControlAccept { } } -pub fn install_service() -> Result<()> { +#[derive(err_derive::Error, Debug)] +pub enum InstallError { + #[error(display = "Unable to connect to service manager")] + ConnectServiceManager(#[error(cause)] windows_service::Error), + + #[error(display = "Unable to create a service")] + CreateService(#[error(cause)] windows_service::Error), +} + +pub fn install_service() -> Result<(), InstallError> { let manager_access = ServiceManagerAccess::CONNECT | ServiceManagerAccess::CREATE_SERVICE; let service_manager = ServiceManager::local_computer(None::<&str>, manager_access) - .chain_err(|| "Unable to connect to service manager")?; + .map_err(InstallError::ConnectServiceManager)?; service_manager - .create_service(get_service_info()?, ServiceAccess::empty()) + .create_service(get_service_info(), ServiceAccess::empty()) .map(|_| ()) - .chain_err(|| "Unable to create a service") + .map_err(InstallError::CreateService) } -fn get_service_info() -> Result<ServiceInfo> { - Ok(ServiceInfo { +fn get_service_info() -> ServiceInfo { + ServiceInfo { name: OsString::from(SERVICE_NAME), display_name: OsString::from(SERVICE_DISPLAY_NAME), service_type: SERVICE_TYPE, @@ -243,5 +250,5 @@ fn get_service_info() -> Result<ServiceInfo> { ], account_name: None, // run as System account_password: None, - }) + } } |
