diff --git a/parity/cli/usage.txt b/parity/cli/usage.txt index 797a5443e..cc7736d31 100644 --- a/parity/cli/usage.txt +++ b/parity/cli/usage.txt @@ -351,6 +351,9 @@ Legacy Options: --extradata STRING Equivalent to --extra-data STRING. --cache MB Equivalent to --cache-size MB. +Internal Options: + --can-restart Executable will auto-restart if exiting with 125. + Miscellaneous Options: -c --config CONFIG Specify a filename containing a configuration file. (default: {flag_config}) diff --git a/parity/main.rs b/parity/main.rs index a435e6230..9d627b363 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -142,12 +142,12 @@ enum PostExecutionAction { Quit, } -fn execute(command: Execute) -> Result { +fn execute(command: Execute, can_restart: bool) -> Result { let logger = setup_log(&command.logger).expect("Logger is initialized only once; qed"); match command.cmd { Cmd::Run(run_cmd) => { - let restart = run::execute(run_cmd, logger)?; + let restart = run::execute(run_cmd, can_restart, logger)?; Ok(if restart { PostExecutionAction::Restart } else { PostExecutionAction::Quit }) }, Cmd::Version => Ok(PostExecutionAction::Print(Args::print_version())), @@ -160,7 +160,7 @@ fn execute(command: Execute) -> Result { } } -fn start() -> Result { +fn start(can_restart: bool) -> Result { let args: Vec = env::args().collect(); let conf = Configuration::parse(&args).unwrap_or_else(|e| e.exit()); @@ -170,7 +170,7 @@ fn start() -> Result { } let cmd = try!(conf.into_command()); - execute(cmd) + execute(cmd, can_restart) } #[cfg(not(feature="stratum"))] @@ -204,19 +204,21 @@ fn latest_exe_path() -> Option { // Starts ~/.parity-updates/parity and returns the code it exits with. fn run_parity() -> Option { + use ::std::ffi::OsString; + let prefix = vec![OsString::from("--can-restart"), OsString::from("--force-direct")]; latest_exe_path().and_then(|exe| process::Command::new(exe) - .args(&env::args_os().collect::>()) - .status() - .map(|es| es.code().unwrap_or(128)) - .ok() - ) + .args(&(env::args_os().chain(prefix.into_iter()).collect::>())) + .status() + .map(|es| es.code().unwrap_or(128)) + .ok() + ) } const PLEASE_RESTART_EXIT_CODE: i32 = 69; // Run our version of parity. // Returns the exit error code. -fn main_direct() -> i32 { +fn main_direct(can_restart: bool) -> i32 { let mut alt_mains = HashMap::new(); sync_main(&mut alt_mains); stratum_main(&mut alt_mains); @@ -224,7 +226,7 @@ fn main_direct() -> i32 { f(); 0 } else { - match start() { + match start(can_restart) { Ok(result) => match result { PostExecutionAction::Print(s) => { info!("{}", s); 0 }, PostExecutionAction::Restart => PLEASE_RESTART_EXIT_CODE, @@ -270,7 +272,7 @@ fn main() { loop { // If we fail to run the updated parity then fallback to local version. trace_main!("Attempting to run latest update ({})...", latest_exe.as_ref().expect("guarded by have_update; latest_exe must exist for have_update; qed").display()); - let exit_code = run_parity().unwrap_or_else(|| { trace_main!("Falling back to local..."); main_direct() }); + let exit_code = run_parity().unwrap_or_else(|| { trace_main!("Falling back to local..."); main_direct(true) }); trace_main!("Latest exited with {}", exit_code); if exit_code != PLEASE_RESTART_EXIT_CODE { trace_main!("Quitting..."); @@ -281,6 +283,7 @@ fn main() { } else { trace_main!("Running direct"); // Otherwise, we're presumably running the version we want. Just run and fall-through. - process::exit(main_direct()); + let can_restart = std::env::args().any(|arg| arg == "--can-restart"); + process::exit(main_direct(can_restart)); } } diff --git a/parity/run.rs b/parity/run.rs index 7d7fbff0c..26e88eb59 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -116,7 +116,7 @@ pub fn open_ui(dapps_conf: &dapps::Configuration, signer_conf: &signer::Configur Ok(()) } -pub fn execute(cmd: RunCmd, logger: Arc) -> Result { +pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc) -> Result { if cmd.ui && cmd.dapps_conf.enabled { // Check if Parity is already running let addr = format!("{}:{}", cmd.dapps_conf.interface, cmd.dapps_conf.port); @@ -415,7 +415,7 @@ pub fn execute(cmd: RunCmd, logger: Arc) -> Result } // Handle exit - wait_for_exit(panic_handler, http_server, ipc_server, dapps_server, signer_server, updater); + wait_for_exit(panic_handler, http_server, ipc_server, dapps_server, signer_server, updater, can_restart); info!("Finishing work, please wait..."); @@ -472,7 +472,8 @@ fn wait_for_exit( _ipc_server: Option, _dapps_server: Option, _signer_server: Option, - updater: Arc + updater: Arc, + can_restart: bool ) -> bool { let exit = Arc::new((Mutex::new(false), Condvar::new())); @@ -485,8 +486,12 @@ fn wait_for_exit( panic_handler.on_panic(move |_reason| { e.1.notify_all(); }); // Handle updater wanting to restart us - let e = exit.clone(); - updater.set_exit_handler(move || { *e.0.lock() = true; e.1.notify_all(); }); + if can_restart { + let e = exit.clone(); + updater.set_exit_handler(move || { *e.0.lock() = true; e.1.notify_all(); }); + } else { + updater.set_exit_handler(|| info!("Update installed; ready for restart.")); + } // Wait for signal let mut l = exit.0.lock();