Fix auto-updater. (#4868)

This commit is contained in:
Gav Wood 2017-03-11 14:46:17 +01:00 committed by Arkadiy Paronyan
parent bcf2245110
commit d15372c8a6
2 changed files with 38 additions and 15 deletions

View File

@ -122,7 +122,7 @@ mod stratum;
use std::{process, env}; use std::{process, env};
use std::collections::HashMap; use std::collections::HashMap;
use std::io::{self as stdio, BufReader, Read, Write}; use std::io::{self as stdio, BufReader, Read, Write};
use std::fs::File; use std::fs::{metadata, File};
use std::path::PathBuf; use std::path::PathBuf;
use util::sha3::sha3; use util::sha3::sha3;
use cli::Args; use cli::Args;
@ -292,8 +292,19 @@ fn main() {
let latest_exe = latest_exe_path(); let latest_exe = latest_exe_path();
let have_update = latest_exe.as_ref().map_or(false, |p| p.exists()); let have_update = latest_exe.as_ref().map_or(false, |p| p.exists());
let is_non_updated_current = exe.as_ref().map_or(false, |exe| latest_exe.as_ref().map_or(false, |lexe| exe.canonicalize().ok() != lexe.canonicalize().ok())); let is_non_updated_current = exe.as_ref().map_or(false, |exe| latest_exe.as_ref().map_or(false, |lexe| exe.canonicalize().ok() != lexe.canonicalize().ok()));
trace_main!("Starting... (have-update: {}, non-updated-current: {})", have_update, is_non_updated_current); let update_is_newer = match (
let exit_code = if have_update && is_non_updated_current { latest_exe.as_ref()
.and_then(|p| metadata(p.as_path()).ok())
.and_then(|m| m.modified().ok()),
exe.as_ref()
.and_then(|p| metadata(p.as_path()).ok())
.and_then(|m| m.modified().ok())
) {
(Some(latest_exe_time), Some(this_exe_time)) if latest_exe_time > this_exe_time => true,
_ => false,
};
trace_main!("Starting... (have-update: {}, non-updated-current: {})", have_update, is_non_updated_current); trace_main!("Starting... (have-update: {}, non-updated-current: {})", have_update, is_non_updated_current);
let exit_code = if have_update && is_non_updated_current && update_is_newer {
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()); 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());
run_parity().unwrap_or_else(|| { trace_main!("Falling back to local..."); main_direct(true) }) run_parity().unwrap_or_else(|| { trace_main!("Falling back to local..."); main_direct(true) })
} else { } else {

View File

@ -210,13 +210,15 @@ impl Updater {
let auto = { let auto = {
let mut s = self.state.lock(); let mut s = self.state.lock();
let fetched = s.fetching.take().unwrap(); let fetched = s.fetching.take().unwrap();
let dest = self.updates_path(&Self::update_file_name(&fetched.version));
if !dest.exists() {
let b = result.map_err(|e| (format!("Unable to fetch update ({}): {:?}", fetched.version, e), false))?; let b = result.map_err(|e| (format!("Unable to fetch update ({}): {:?}", fetched.version, e), false))?;
info!(target: "updater", "Fetched latest version ({}) OK to {}", fetched.version, b.display()); info!(target: "updater", "Fetched latest version ({}) OK to {}", fetched.version, b.display());
let dest = self.updates_path(&Self::update_file_name(&fetched.version));
fs::create_dir_all(dest.parent().expect("at least one thing pushed; qed")).map_err(|e| (format!("Unable to create updates path: {:?}", e), true))?; fs::create_dir_all(dest.parent().expect("at least one thing pushed; qed")).map_err(|e| (format!("Unable to create updates path: {:?}", e), true))?;
fs::copy(&b, &dest).map_err(|e| (format!("Unable to copy update: {:?}", e), true))?; fs::copy(&b, &dest).map_err(|e| (format!("Unable to copy update: {:?}", e), true))?;
restrict_permissions_owner(&dest, false, true).map_err(|e| (format!("Unable to update permissions: {}", e), true))?; restrict_permissions_owner(&dest, false, true).map_err(|e| (format!("Unable to update permissions: {}", e), true))?;
info!(target: "updater", "Installed updated binary to {}", dest.display()); info!(target: "updater", "Installed updated binary to {}", dest.display());
}
let auto = match self.update_policy.filter { let auto = match self.update_policy.filter {
UpdateFilter::All => true, UpdateFilter::All => true,
UpdateFilter::Critical if fetched.is_critical /* TODO: or is on a bad fork */ => true, UpdateFilter::Critical if fetched.is_critical /* TODO: or is on a bad fork */ => true,
@ -271,9 +273,16 @@ impl Updater {
let running_later = latest.track.version.version < self.version_info().version; let running_later = latest.track.version.version < self.version_info().version;
let running_latest = latest.track.version.hash == self.version_info().hash; let running_latest = latest.track.version.hash == self.version_info().hash;
let already_have_latest = s.installed.as_ref().or(s.ready.as_ref()).map_or(false, |t| *t == latest.track); let already_have_latest = s.installed.as_ref().or(s.ready.as_ref()).map_or(false, |t| *t == latest.track);
if self.update_policy.enable_downloading && !running_later && !running_latest && !already_have_latest { if self.update_policy.enable_downloading && !running_later && !running_latest && !already_have_latest {
if let Some(b) = latest.track.binary { if let Some(b) = latest.track.binary {
if s.fetching.is_none() { if s.fetching.is_none() {
if self.updates_path(&Self::update_file_name(&latest.track.version)).exists() {
info!(target: "updater", "Already fetched binary.");
s.fetching = Some(latest.track.clone());
drop(s);
self.fetch_done(Ok(PathBuf::new()));
} else {
info!(target: "updater", "Attempting to get parity binary {}", b); info!(target: "updater", "Attempting to get parity binary {}", b);
s.fetching = Some(latest.track.clone()); s.fetching = Some(latest.track.clone());
drop(s); drop(s);
@ -283,6 +292,7 @@ impl Updater {
} }
} }
} }
}
trace!(target: "updater", "Fork: this/current/latest/latest-known: {}/#{}/#{}/#{}", match latest.this_fork { Some(f) => format!("#{}", f), None => "unknown".into(), }, current_number, latest.track.fork, latest.fork); trace!(target: "updater", "Fork: this/current/latest/latest-known: {}/#{}/#{}/#{}", match latest.this_fork { Some(f) => format!("#{}", f), None => "unknown".into(), }, current_number, latest.track.fork, latest.fork);
if let Some(this_fork) = latest.this_fork { if let Some(this_fork) = latest.this_fork {
@ -356,6 +366,8 @@ impl Service for Updater {
s.installed = Some(r); s.installed = Some(r);
if let Some(ref h) = *self.exit_handler.lock() { if let Some(ref h) = *self.exit_handler.lock() {
(*h)(); (*h)();
} else {
info!("Update installed; ready for restart.");
} }
Ok(true) Ok(true)
} }