Added possibility to generate unique id for each build
This commit is contained in:
parent
ce400dbe14
commit
6c49fad2fa
@ -8,6 +8,7 @@ clap = "2.32.0"
|
|||||||
dirs = "1.0.4"
|
dirs = "1.0.4"
|
||||||
reqwest = "0.9.2"
|
reqwest = "0.9.2"
|
||||||
tempdir = "0.3.7"
|
tempdir = "0.3.7"
|
||||||
|
rand = "0.6"
|
||||||
flate2 = "1.0"
|
flate2 = "1.0"
|
||||||
tar = "0.4"
|
tar = "0.4"
|
||||||
lazy_static = "1.1.0"
|
lazy_static = "1.1.0"
|
@ -3,6 +3,7 @@ extern crate dirs;
|
|||||||
extern crate flate2;
|
extern crate flate2;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
|
extern crate rand;
|
||||||
extern crate reqwest;
|
extern crate reqwest;
|
||||||
extern crate tar;
|
extern crate tar;
|
||||||
extern crate tempdir;
|
extern crate tempdir;
|
||||||
@ -10,6 +11,8 @@ extern crate tempdir;
|
|||||||
use clap::{App, AppSettings, Arg};
|
use clap::{App, AppSettings, Arg};
|
||||||
use flate2::Compression;
|
use flate2::Compression;
|
||||||
use flate2::write::GzEncoder;
|
use flate2::write::GzEncoder;
|
||||||
|
use rand::{thread_rng, Rng};
|
||||||
|
use rand::distributions::Alphanumeric;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
@ -26,7 +29,8 @@ const APP_NAME: &str = env!("CARGO_PKG_NAME");
|
|||||||
const AUTHOR: &str = env!("CARGO_PKG_AUTHORS");
|
const AUTHOR: &str = env!("CARGO_PKG_AUTHORS");
|
||||||
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
const RUNNER_MAGIC: &[u8] = b"tVQhhsFFlGGD3oWV4lEPST8I8FEPP54IM0q7daes4E1y3p2U2wlJRYmWmjPYfkhZ0PlT14Ls0j8fdDkoj33f2BlRJavLj3mWGibJsGt5uLAtrCDtvxikZ8UX2mQDCrgE\0";
|
const RUNNER_EXEC_MAGIC: &[u8] = b"tVQhhsFFlGGD3oWV4lEPST8I8FEPP54IM0q7daes4E1y3p2U2wlJRYmWmjPYfkhZ0PlT14Ls0j8fdDkoj33f2BlRJavLj3mWGibJsGt5uLAtrCDtvxikZ8UX2mQDCrgE\0";
|
||||||
|
const RUNNER_UID_MAGIC: &[u8] = b"DR1PWsJsM6KxNbng9Y38\0";
|
||||||
|
|
||||||
const RUNNER_LINUX_X64: &[u8] = include_bytes!("../../target/x86_64-unknown-linux-gnu/release/warp-runner");
|
const RUNNER_LINUX_X64: &[u8] = include_bytes!("../../target/x86_64-unknown-linux-gnu/release/warp-runner");
|
||||||
const RUNNER_MACOS_X64: &[u8] = include_bytes!("../../target/x86_64-apple-darwin/release/warp-runner");
|
const RUNNER_MACOS_X64: &[u8] = include_bytes!("../../target/x86_64-apple-darwin/release/warp-runner");
|
||||||
@ -51,34 +55,38 @@ macro_rules! bail {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn patch_runner(arch: &str, exec_name: &str) -> io::Result<Vec<u8>> {
|
fn patch_runner(arch: &str, exec_name: &str, uid: &str) -> io::Result<Vec<u8>> {
|
||||||
// Read runner executable in memory
|
// Read runner executable in memory
|
||||||
let runner_contents = RUNNER_BY_ARCH.get(arch).unwrap();
|
let runner_contents = RUNNER_BY_ARCH.get(arch).unwrap();
|
||||||
let mut buf = runner_contents.to_vec();
|
let mut buf = runner_contents.to_vec();
|
||||||
|
|
||||||
// Set the correct target executable name into the local magic buffer
|
write_magic(&mut buf, RUNNER_UID_MAGIC, uid);
|
||||||
let magic_len = RUNNER_MAGIC.len();
|
write_magic(&mut buf, RUNNER_EXEC_MAGIC, exec_name);
|
||||||
|
Ok(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_magic(buf: &mut Vec<u8>, magic: &[u8], new_value: &str) {
|
||||||
|
// Set the correct target executable name into the local magic buffer
|
||||||
|
let magic_len = magic.len();
|
||||||
let mut new_magic = vec![0; magic_len];
|
let mut new_magic = vec![0; magic_len];
|
||||||
new_magic[..exec_name.len()].clone_from_slice(exec_name.as_bytes());
|
new_magic[..new_value.len()].clone_from_slice(new_value.as_bytes());
|
||||||
|
|
||||||
// Find the magic buffer offset inside the runner executable
|
// Find the magic buffer offset inside the runner executable
|
||||||
let mut offs_opt = None;
|
let mut offs_opt = None;
|
||||||
for (i, chunk) in buf.windows(magic_len).enumerate() {
|
for (i, chunk) in buf.windows(magic_len).enumerate() {
|
||||||
if chunk == RUNNER_MAGIC {
|
if chunk == magic {
|
||||||
offs_opt = Some(i);
|
offs_opt = Some(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if offs_opt.is_none() {
|
if offs_opt.is_none() {
|
||||||
return Err(io::Error::new(io::ErrorKind::Other, "no magic found inside runner"));
|
bail!("no magic found inside runner");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace the magic with the new one that points to the target executable
|
// Replace the magic with the new one that points to the target executable
|
||||||
let offs = offs_opt.unwrap();
|
let offs = offs_opt.unwrap();
|
||||||
buf[offs..offs + magic_len].clone_from_slice(&new_magic);
|
buf[offs..offs + magic_len].clone_from_slice(&new_magic);
|
||||||
|
|
||||||
Ok(buf)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_tgz(dirs: &Vec<&Path>, out: &Path) -> io::Result<()> {
|
fn create_tgz(dirs: &Vec<&Path>, out: &Path) -> io::Result<()> {
|
||||||
@ -145,6 +153,13 @@ fn check_executable_exists(exec_path: &Path){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn generate_uid() -> String {
|
||||||
|
return thread_rng()
|
||||||
|
.sample_iter(&Alphanumeric)
|
||||||
|
.take(RUNNER_UID_MAGIC.len() - 1)
|
||||||
|
.collect();
|
||||||
|
}
|
||||||
|
|
||||||
fn main() -> Result<(), Box<Error>> {
|
fn main() -> Result<(), Box<Error>> {
|
||||||
let args = App::new(APP_NAME)
|
let args = App::new(APP_NAME)
|
||||||
.settings(&[AppSettings::ArgRequiredElseHelp, AppSettings::ColoredHelp])
|
.settings(&[AppSettings::ArgRequiredElseHelp, AppSettings::ColoredHelp])
|
||||||
@ -200,6 +215,14 @@ fn main() -> Result<(), Box<Error>> {
|
|||||||
.display_order(6)
|
.display_order(6)
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.required(true))
|
.required(true))
|
||||||
|
.arg(Arg::with_name("unique_id")
|
||||||
|
.short("q")
|
||||||
|
.long("unique_id")
|
||||||
|
.value_name("unique_id")
|
||||||
|
.help("Generate unique id for each package build")
|
||||||
|
.display_order(7)
|
||||||
|
.takes_value(false)
|
||||||
|
.required(false))
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
let arch = args.value_of("arch").unwrap();
|
let arch = args.value_of("arch").unwrap();
|
||||||
@ -223,7 +246,7 @@ fn main() -> Result<(), Box<Error>> {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let exec_name = args.value_of("exec").unwrap();
|
let exec_name = args.value_of("exec").unwrap();
|
||||||
if exec_name.len() >= RUNNER_MAGIC.len() {
|
if exec_name.len() >= RUNNER_EXEC_MAGIC.len() {
|
||||||
bail!("Executable name is too long, please consider using a shorter name");
|
bail!("Executable name is too long, please consider using a shorter name");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,7 +256,13 @@ fn main() -> Result<(), Box<Error>> {
|
|||||||
check_executable_exists(&exec_path);
|
check_executable_exists(&exec_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
let runner_buf = patch_runner(&arch, &exec_name)?;
|
let mut uid:String = "".to_string();
|
||||||
|
let do_generate_uid = args.is_present("unique_id");
|
||||||
|
if do_generate_uid {
|
||||||
|
uid = generate_uid();
|
||||||
|
}
|
||||||
|
|
||||||
|
let runner_buf = patch_runner(&arch, &exec_name, &uid)?;
|
||||||
|
|
||||||
create_tgz(&input_dirs, &main_tgz_path)?;
|
create_tgz(&input_dirs, &main_tgz_path)?;
|
||||||
|
|
||||||
|
@ -16,17 +16,26 @@ mod extractor;
|
|||||||
mod executor;
|
mod executor;
|
||||||
|
|
||||||
static TARGET_FILE_NAME_BUF: &'static [u8] = b"tVQhhsFFlGGD3oWV4lEPST8I8FEPP54IM0q7daes4E1y3p2U2wlJRYmWmjPYfkhZ0PlT14Ls0j8fdDkoj33f2BlRJavLj3mWGibJsGt5uLAtrCDtvxikZ8UX2mQDCrgE\0";
|
static TARGET_FILE_NAME_BUF: &'static [u8] = b"tVQhhsFFlGGD3oWV4lEPST8I8FEPP54IM0q7daes4E1y3p2U2wlJRYmWmjPYfkhZ0PlT14Ls0j8fdDkoj33f2BlRJavLj3mWGibJsGt5uLAtrCDtvxikZ8UX2mQDCrgE\0";
|
||||||
|
static TARGET_UID_BUF: &'static [u8] = b"DR1PWsJsM6KxNbng9Y38\0";
|
||||||
|
|
||||||
|
fn build_uid() -> &'static str {
|
||||||
|
return read_magic("TARGET_UID_BUF", &TARGET_UID_BUF)
|
||||||
|
}
|
||||||
|
|
||||||
fn target_file_name() -> &'static str {
|
fn target_file_name() -> &'static str {
|
||||||
let nul_pos = TARGET_FILE_NAME_BUF.iter()
|
return read_magic("TARGET_FILE_NAME_BUF", &TARGET_FILE_NAME_BUF)
|
||||||
.position(|elem| *elem == b'\0')
|
}
|
||||||
.expect("TARGET_FILE_NAME_BUF has no NUL terminator");
|
|
||||||
|
|
||||||
let slice = &TARGET_FILE_NAME_BUF[..(nul_pos + 1)];
|
fn read_magic(magic_name: &str, magic: &'static [u8]) -> &'static str {
|
||||||
|
let nul_pos = magic.iter()
|
||||||
|
.position(|elem| *elem == b'\0')
|
||||||
|
.expect(&format!("{} has no NUL terminator", magic_name));
|
||||||
|
|
||||||
|
let slice = &magic[..(nul_pos + 1)];
|
||||||
CStr::from_bytes_with_nul(slice)
|
CStr::from_bytes_with_nul(slice)
|
||||||
.expect("Can't convert TARGET_FILE_NAME_BUF slice to CStr")
|
.expect(&format!("Can't convert {} slice to CStr", magic_name))
|
||||||
.to_str()
|
.to_str()
|
||||||
.expect("Can't convert TARGET_FILE_NAME_BUF CStr to str")
|
.expect(&format!("Can't convert {} CStr to str", magic_name))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cache_path(target: &str) -> PathBuf {
|
fn cache_path(target: &str) -> PathBuf {
|
||||||
@ -48,12 +57,17 @@ fn main() -> Result<(), Box<Error>> {
|
|||||||
simple_logger::init_with_level(Level::Trace)?;
|
simple_logger::init_with_level(Level::Trace)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
let build_uid = build_uid();
|
||||||
let self_path = env::current_exe()?;
|
let self_path = env::current_exe()?;
|
||||||
let self_file_name = self_path.file_name().unwrap();
|
let self_file_name = self_path.file_name().unwrap();
|
||||||
let cache_path = cache_path(&self_file_name.to_string_lossy());
|
let cache_folder_name = format!("{}.{}", self_file_name.to_string_lossy(), build_uid);
|
||||||
|
let cache_path = cache_path(&cache_folder_name);
|
||||||
|
|
||||||
trace!("self_path={:?}", self_path);
|
trace!("self_path={:?}", self_path);
|
||||||
trace!("self_file_name={:?}", self_file_name);
|
trace!("self_file_name={:?}", self_file_name);
|
||||||
|
trace!("build_uid={:?}", build_uid);
|
||||||
trace!("cache_path={:?}", cache_path);
|
trace!("cache_path={:?}", cache_path);
|
||||||
|
|
||||||
let target_file_name = target_file_name();
|
let target_file_name = target_file_name();
|
||||||
|
Loading…
Reference in New Issue
Block a user