Use file contents instead of symlink.
This commit is contained in:
parent
7a1539cfb5
commit
2865cbaf70
@ -117,7 +117,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, Write};
|
use std::io::{self as stdio, BufReader, Read, Write};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use util::sha3::sha3;
|
use util::sha3::sha3;
|
||||||
@ -190,21 +190,26 @@ fn sync_main(alt_mains: &mut HashMap<String, fn()>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: merge with version in Updater.
|
// TODO: merge with version in Updater.
|
||||||
fn updates_latest() -> PathBuf {
|
fn updates_path(name: &str) -> PathBuf {
|
||||||
let mut dest = PathBuf::from(env::home_dir().unwrap().to_str().expect("env filesystem paths really should be valid; qed"));
|
let mut dest = PathBuf::from(env::home_dir().unwrap().to_str().expect("env filesystem paths really should be valid; qed"));
|
||||||
dest.push(".parity-updates");
|
dest.push(".parity-updates");
|
||||||
dest.push("parity");
|
dest.push(name);
|
||||||
dest
|
dest
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn latest_exe_path() -> Option<PathBuf> {
|
||||||
|
File::open(updates_path("latest")).ok()
|
||||||
|
.and_then(|mut f| { let mut exe = String::new(); f.read_to_string(&mut exe).ok().map(|_| updates_path(&exe)) })
|
||||||
|
}
|
||||||
|
|
||||||
// Starts ~/.parity-updates/parity and returns the code it exits with.
|
// Starts ~/.parity-updates/parity and returns the code it exits with.
|
||||||
fn run_parity() -> Option<i32> {
|
fn run_parity() -> Option<i32> {
|
||||||
let exe = updates_latest();
|
latest_exe_path().and_then(|exe| process::Command::new(exe)
|
||||||
process::Command::new(exe)
|
|
||||||
.args(&env::args_os().collect::<Vec<_>>())
|
.args(&env::args_os().collect::<Vec<_>>())
|
||||||
.status()
|
.status()
|
||||||
.map(|es| es.code().unwrap_or(128))
|
.map(|es| es.code().unwrap_or(128))
|
||||||
.ok()
|
.ok()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const PLEASE_RESTART_EXIT_CODE: i32 = 69;
|
const PLEASE_RESTART_EXIT_CODE: i32 = 69;
|
||||||
@ -254,16 +259,17 @@ fn main() {
|
|||||||
let force_direct = std::env::args().any(|arg| arg == "--force-direct");
|
let force_direct = std::env::args().any(|arg| arg == "--force-direct");
|
||||||
let exe = std::env::current_exe().ok();
|
let exe = std::env::current_exe().ok();
|
||||||
let development = exe.as_ref().and_then(|p| p.parent().and_then(|p| p.parent()).and_then(|p| p.file_name()).map(|n| n == "target")).unwrap_or(false);
|
let development = exe.as_ref().and_then(|p| p.parent().and_then(|p| p.parent()).and_then(|p| p.file_name()).map(|n| n == "target")).unwrap_or(false);
|
||||||
let same_name = exe.as_ref().and_then(|p| p.file_stem().map(|s| s == "parity")).unwrap_or(false);
|
let same_name = exe.as_ref().map(|p| p.file_stem().map_or(false, |s| s == "parity") && p.extension().map_or(true, |x| x == "exe")).unwrap_or(false);
|
||||||
let have_update = updates_latest().exists();
|
let latest_exe = latest_exe_path();
|
||||||
let is_non_updated_current = exe.map_or(false, |p| p.canonicalize().ok() != updates_latest().canonicalize().ok());
|
let have_update = latest_exe.as_ref().map_or(false, |p| p.exists());
|
||||||
|
let is_non_updated_current = exe.map_or(false, |exe| latest_exe.as_ref().map_or(false, |lexe| exe.canonicalize().ok() != lexe.canonicalize().ok()));
|
||||||
trace_main!("Starting up {} (force-direct: {}, development: {}, same-name: {}, have-update: {}, non-updated-current: {})", std::env::current_exe().map(|x| format!("{}", x.display())).unwrap_or("<unknown>".to_owned()), force_direct, development, same_name, have_update, is_non_updated_current);
|
trace_main!("Starting up {} (force-direct: {}, development: {}, same-name: {}, have-update: {}, non-updated-current: {})", std::env::current_exe().map(|x| format!("{}", x.display())).unwrap_or("<unknown>".to_owned()), force_direct, development, same_name, have_update, is_non_updated_current);
|
||||||
if !force_direct && !development && same_name && have_update && is_non_updated_current {
|
if !force_direct && !development && same_name && have_update && is_non_updated_current {
|
||||||
// looks like we're not running ~/.parity-updates/parity when the user is expecting otherwise.
|
// looks like we're not running ~/.parity-updates/parity when the user is expecting otherwise.
|
||||||
// Everything run inside a loop, so we'll be able to restart from the child into a new version seamlessly.
|
// Everything run inside a loop, so we'll be able to restart from the child into a new version seamlessly.
|
||||||
loop {
|
loop {
|
||||||
// If we fail to run the updated parity then fallback to local version.
|
// If we fail to run the updated parity then fallback to local version.
|
||||||
trace_main!("Attempting to run latest update...");
|
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() });
|
||||||
trace_main!("Latest exited with {}", exit_code);
|
trace_main!("Latest exited with {}", exit_code);
|
||||||
if exit_code != PLEASE_RESTART_EXIT_CODE {
|
if exit_code != PLEASE_RESTART_EXIT_CODE {
|
||||||
|
@ -15,8 +15,9 @@
|
|||||||
// 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::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use std::{io, os, fs, env};
|
use std::{fs, env};
|
||||||
use std::path::{Path, PathBuf};
|
use std::io::Write;
|
||||||
|
use std::path::{PathBuf};
|
||||||
use util::misc::{VersionInfo, ReleaseTrack/*, platform*/};
|
use util::misc::{VersionInfo, ReleaseTrack/*, platform*/};
|
||||||
use util::{Address, H160, H256, FixedHash, Mutex, Bytes};
|
use util::{Address, H160, H256, FixedHash, Mutex, Bytes};
|
||||||
use super::operations::Operations;
|
use super::operations::Operations;
|
||||||
@ -113,16 +114,6 @@ fn platform() -> String {
|
|||||||
"test".to_owned()
|
"test".to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[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)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Updater {
|
impl Updater {
|
||||||
pub fn new(client: Weak<BlockChainClient>, update_policy: UpdatePolicy) -> Arc<Self> {
|
pub fn new(client: Weak<BlockChainClient>, update_policy: UpdatePolicy) -> Arc<Self> {
|
||||||
let mut u = Updater {
|
let mut u = Updater {
|
||||||
@ -170,10 +161,10 @@ impl Updater {
|
|||||||
(|| -> Result<bool, String> {
|
(|| -> Result<bool, String> {
|
||||||
let mut s = self.state.lock();
|
let mut s = self.state.lock();
|
||||||
if let Some(r) = s.ready.take() {
|
if let Some(r) = s.ready.take() {
|
||||||
let p = Self::update_file_path(&r.version);
|
let p = Self::update_file_name(&r.version);
|
||||||
let n = Self::updates_latest();
|
let n = Self::updates_path("latest");
|
||||||
let _ = fs::remove_file(&n);
|
// TODO: creating then writing is a bit fragile. would be nice to make it atomic.
|
||||||
match symlink(p, n) {
|
match fs::File::create(&n).and_then(|mut f| f.write_all(p.as_bytes())) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
info!("Completed upgrade to {}", &r.version);
|
info!("Completed upgrade to {}", &r.version);
|
||||||
s.installed = Some(r);
|
s.installed = Some(r);
|
||||||
@ -249,17 +240,14 @@ impl Updater {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_file_path(v: &VersionInfo) -> PathBuf {
|
fn update_file_name(v: &VersionInfo) -> String {
|
||||||
let mut dest = PathBuf::from(env::home_dir().unwrap().to_str().expect("env filesystem paths really should be valid; qed"));
|
format!("parity-{}.{}.{}-{:?}", v.version.major, v.version.minor, v.version.patch, v.hash)
|
||||||
dest.push(".parity-updates");
|
|
||||||
dest.push(format!("parity-{}.{}.{}-{:?}", v.version.major, v.version.minor, v.version.patch, v.hash));
|
|
||||||
dest
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn updates_latest() -> PathBuf {
|
fn updates_path(name: &str) -> PathBuf {
|
||||||
let mut dest = PathBuf::from(env::home_dir().unwrap().to_str().expect("env filesystem paths really should be valid; qed"));
|
let mut dest = PathBuf::from(env::home_dir().unwrap().to_str().expect("env filesystem paths really should be valid; qed"));
|
||||||
dest.push(".parity-updates");
|
dest.push(".parity-updates");
|
||||||
dest.push("parity");
|
dest.push(name);
|
||||||
dest
|
dest
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,7 +258,7 @@ impl Updater {
|
|||||||
let fetched = s.fetching.take().unwrap();
|
let fetched = s.fetching.take().unwrap();
|
||||||
let b = result.map_err(|e| format!("Unable to fetch update ({}): {:?}", fetched.version, e))?;
|
let b = result.map_err(|e| format!("Unable to fetch update ({}): {:?}", fetched.version, e))?;
|
||||||
info!("Fetched latest version ({}) OK to {}", fetched.version, b.display());
|
info!("Fetched latest version ({}) OK to {}", fetched.version, b.display());
|
||||||
let dest = Self::update_file_path(&fetched.version);
|
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))?;
|
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))?;
|
fs::copy(&b, &dest).map_err(|e| format!("Unable to copy update: {:?}", e))?;
|
||||||
info!("Copied file to {}", dest.display());
|
info!("Copied file to {}", dest.display());
|
||||||
|
Loading…
Reference in New Issue
Block a user