Cleanups and avoid redownloading.
This commit is contained in:
parent
c2b6be95c8
commit
e5e6b77984
@ -678,6 +678,9 @@ impl Client {
|
|||||||
self.check_snooze();
|
self.check_snooze();
|
||||||
if let Some(ref mut updater) = *self.updater.lock() {
|
if let Some(ref mut updater) = *self.updater.lock() {
|
||||||
updater.tick();
|
updater.tick();
|
||||||
|
if updater.installed.is_some() {
|
||||||
|
info!("Client should restart now.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use std::sync::{Weak};
|
use std::sync::{Weak};
|
||||||
use std::{fs, env};
|
use std::{io, os, fs, env};
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
use util::misc::{VersionInfo, ReleaseTrack/*, platform*/};
|
use util::misc::{VersionInfo, ReleaseTrack/*, platform*/};
|
||||||
use util::{Address, H160, H256, FixedHash, Mutex};
|
use util::{Address, H160, H256, FixedHash, Mutex};
|
||||||
use client::operations::Operations;
|
use client::operations::Operations;
|
||||||
@ -54,7 +54,8 @@ pub struct Updater {
|
|||||||
// This does change
|
// This does change
|
||||||
pub latest: Option<OperationsInfo>,
|
pub latest: Option<OperationsInfo>,
|
||||||
pub ready: Option<ReleaseInfo>,
|
pub ready: Option<ReleaseInfo>,
|
||||||
|
// If Some, client should restart itself.
|
||||||
|
pub installed: Option<ReleaseInfo>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const CLIENT_ID: &'static str = "parity";
|
const CLIENT_ID: &'static str = "parity";
|
||||||
@ -75,6 +76,7 @@ impl Updater {
|
|||||||
this_fork: None,
|
this_fork: None,
|
||||||
latest: None,
|
latest: None,
|
||||||
ready: None,
|
ready: None,
|
||||||
|
installed: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
u.this_fork = u.operations.release(CLIENT_ID, &u.this.hash.into()).ok()
|
u.this_fork = u.operations.release(CLIENT_ID, &u.this.hash.into()).ok()
|
||||||
@ -107,12 +109,40 @@ impl Updater {
|
|||||||
self.ready.clone()
|
self.ready.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()> {
|
||||||
|
os::windows::fs::symlink_file(src, dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()> {
|
||||||
|
os::unix::fs::symlink(src, dst)
|
||||||
|
}
|
||||||
|
|
||||||
/// Actually upgrades the client. Assumes that the binary has been downloaded.
|
/// Actually upgrades the client. Assumes that the binary has been downloaded.
|
||||||
/// @returns `true` on success.
|
/// @returns `true` on success.
|
||||||
pub fn execute_upgrade(&mut self) -> bool {
|
pub fn execute_upgrade(&mut self) -> bool {
|
||||||
// TODO: link ~/.parity-updates/parity to self.ready
|
(|| -> Result<bool, String> {
|
||||||
// TODO: restart parity.
|
if let Some(r) = self.ready.take() {
|
||||||
unimplemented!()
|
let p = Self::update_file_path(&r.version);
|
||||||
|
let n = Self::updates_latest();
|
||||||
|
let _ = fs::remove_file(&n);
|
||||||
|
match Self::symlink(p, n) {
|
||||||
|
Ok(_) => {
|
||||||
|
info!("Completed upgrade to {}", &r.version);
|
||||||
|
self.installed = Some(r);
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
self.ready = Some(r);
|
||||||
|
Err(format!("Unable to create soft-link for update {:?}", e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warn!("Execute upgrade called when no upgrade ready.");
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
})().unwrap_or_else(|e| { warn!("{}", e); false })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true iff the current version is capable of forming consensus.
|
/// Returns true iff the current version is capable of forming consensus.
|
||||||
@ -165,37 +195,40 @@ impl Updater {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetch_done(&mut self, _r: Result<PathBuf, fetch::Error>) {
|
fn update_file_path(v: &VersionInfo) -> PathBuf {
|
||||||
let fetched = self.fetching.lock().take().unwrap();
|
let mut dest = PathBuf::from(env::home_dir().unwrap().to_str().expect("env filesystem paths really should be valid; qed"));
|
||||||
match _r {
|
dest.push(".parity-updates");
|
||||||
Ok(b) => {
|
dest.push(format!("parity-{}.{}.{}-{:?}", v.version.major, v.version.minor, v.version.patch, v.hash));
|
||||||
info!("Fetched latest version ({}) OK to {}", fetched.version, b.display());
|
dest
|
||||||
let mut dest = PathBuf::from(env::home_dir().unwrap().to_str().expect("env filesystem paths really should be valid; qed"));
|
}
|
||||||
dest.push(".parity-updates");
|
|
||||||
match fs::create_dir_all(&dest) {
|
fn updates_latest() -> PathBuf {
|
||||||
Ok(_) => {
|
let mut dest = PathBuf::from(env::home_dir().unwrap().to_str().expect("env filesystem paths really should be valid; qed"));
|
||||||
dest.push(format!("parity-{}-{:?}", fetched.version, fetched.version.hash));
|
dest.push(".parity-updates");
|
||||||
match fs::copy(&b, &dest) {
|
dest.push("parity");
|
||||||
Ok(_) => {
|
dest
|
||||||
info!("Copied file to {}", dest.display());
|
}
|
||||||
let auto = match self.update_policy.filter {
|
|
||||||
UpdateFilter::All => true,
|
fn fetch_done(&mut self, result: Result<PathBuf, fetch::Error>) {
|
||||||
UpdateFilter::Critical if fetched.is_critical /* TODO: or is on a bad fork */ => true,
|
(|| -> Result<(), String> {
|
||||||
_ => false,
|
let fetched = self.fetching.lock().take().unwrap();
|
||||||
};
|
let b = result.map_err(|e| format!("Unable to fetch update ({}): {:?}", fetched.version, e))?;
|
||||||
self.ready = Some(fetched);
|
info!("Fetched latest version ({}) OK to {}", fetched.version, b.display());
|
||||||
if auto {
|
let dest = Self::update_file_path(&fetched.version);
|
||||||
self.execute_upgrade();
|
fs::create_dir_all(dest.parent().expect("at least one thing pushed; qed")).map_err(|e| format!("Unable to create updates path: {:?}", e))?;
|
||||||
}
|
fs::copy(&b, &dest).map_err(|e| format!("Unable to copy update: {:?}", e))?;
|
||||||
},
|
info!("Copied file to {}", dest.display());
|
||||||
Err(e) => warn!("Unable to copy update: {:?}", e),
|
let auto = match self.update_policy.filter {
|
||||||
}
|
UpdateFilter::All => true,
|
||||||
},
|
UpdateFilter::Critical if fetched.is_critical /* TODO: or is on a bad fork */ => true,
|
||||||
Err(e) => warn!("Unable to create updates path: {:?}", e),
|
_ => false,
|
||||||
}
|
};
|
||||||
},
|
self.ready = Some(fetched);
|
||||||
Err(e) => warn!("Unable to fetch update ({}): {:?}", fetched.version, e),
|
if auto {
|
||||||
}
|
self.execute_upgrade();
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
})().unwrap_or_else(|e| warn!("{}", e));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick(&mut self) {
|
pub fn tick(&mut self) {
|
||||||
@ -215,13 +248,19 @@ impl Updater {
|
|||||||
"unreleased".into()
|
"unreleased".into()
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
if self.update_policy.enable_downloading && latest.track.version.hash != self.version_info().hash && self.ready.as_ref().map_or(true, |t| *t != latest.track) {
|
if self.update_policy.enable_downloading && latest.track.version.hash != self.version_info().hash && self.installed.as_ref().or(self.ready.as_ref()).map_or(true, |t| *t != latest.track) {
|
||||||
if let Some(b) = latest.track.binary {
|
if let Some(b) = latest.track.binary {
|
||||||
let mut fetching = self.fetching.lock();
|
let mut fetching = self.fetching.lock();
|
||||||
if fetching.is_none() {
|
if fetching.is_none() {
|
||||||
info!("Attempting to get parity binary {}", b);
|
info!("Attempting to get parity binary {}", b);
|
||||||
let c = self.client.clone();
|
let c = self.client.clone();
|
||||||
let f = move |r: Result<PathBuf, fetch::Error>| if let Some(c) = c.upgrade() { c.updater().as_mut().expect("updater exists; updater only owned by client; qed").fetch_done(r); };
|
let f = move |r: Result<PathBuf, fetch::Error>| {
|
||||||
|
if let Some(client) = c.upgrade() {
|
||||||
|
if let Some(updater) = client.updater().as_mut() {
|
||||||
|
updater.fetch_done(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
if let Some(fetch) = self.fetch.clone().upgrade() {
|
if let Some(fetch) = self.fetch.clone().upgrade() {
|
||||||
fetch.fetch(b, Box::new(f)).ok();
|
fetch.fetch(b, Box::new(f)).ok();
|
||||||
*fetching = Some(latest.track.clone());
|
*fetching = Some(latest.track.clone());
|
||||||
|
Loading…
Reference in New Issue
Block a user