// Copyright 2015, 2016 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // Parity is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with Parity. If not, see . //! Parity micro-service helpers use nanoipc; use ipc; use std; use std::sync::Arc; use hypervisor::HypervisorServiceClient; use hypervisor::service::IpcModuleId; use ctrlc::CtrlC; use std::sync::atomic::{AtomicBool, Ordering}; use nanoipc::{IpcInterface, GuardedSocket, NanoSocket}; use ipc::WithSocket; use ethcore_logger::{Config as LogConfig, setup_log}; use docopt::Docopt; #[derive(Debug)] pub enum BootError { ReadArgs(std::io::Error), DecodeArgs(ipc::binary::BinaryError), DependencyConnect(nanoipc::SocketError), } pub fn host_service(addr: &str, stop_guard: Arc, service: Arc) where T: IpcInterface { let socket_url = addr.to_owned(); std::thread::spawn(move || { let mut worker = nanoipc::Worker::::new(&service); worker.add_reqrep(&socket_url).unwrap(); while !stop_guard.load(Ordering::SeqCst) { worker.poll(); } }); } pub fn payload() -> Result { use std::io; use std::io::Read; let mut buffer = Vec::new(); io::stdin().read_to_end(&mut buffer).map_err(BootError::ReadArgs)?; ipc::binary::deserialize::(&buffer).map_err(BootError::DecodeArgs) } pub fn register(hv_url: &str, control_url: &str, module_id: IpcModuleId) -> GuardedSocket>{ let hypervisor_client = nanoipc::fast_client::>(hv_url).unwrap(); hypervisor_client.handshake().unwrap(); hypervisor_client.module_ready(module_id, control_url.to_owned()); hypervisor_client } pub fn dependency>(url: &str) -> Result, BootError> { nanoipc::generic_client::(url).map_err(BootError::DependencyConnect) } pub fn main_thread() -> Arc { let stop = Arc::new(AtomicBool::new(false)); let ctrc_stop = stop.clone(); CtrlC::set_handler(move || { ctrc_stop.store(true, Ordering::Relaxed); }); stop } pub fn setup_cli_logger(svc_name: &str) { let usage = format!(" Ethcore {} service Usage: parity {} [options] Options: -l --logging LOGGING Specify the logging level. Must conform to the same format as RUST_LOG. --log-file FILENAME Specify a filename into which logging should be directed. --no-color Don't use terminal color codes in output. ", svc_name, svc_name); #[derive(Debug, RustcDecodable)] struct Args { flag_logging: Option, flag_log_file: Option, flag_no_color: bool, } impl Args { pub fn log_settings(&self) -> LogConfig { LogConfig { color: self.flag_no_color || cfg!(windows), mode: self.flag_logging.clone(), file: self.flag_log_file.clone(), } } } let args: Args = Docopt::new(usage) .and_then(|d| d.decode()) .unwrap_or_else(|e| e.exit()); setup_log(&args.log_settings()).expect("Log initialization failure"); }