Implement results merging

This commit is contained in:
Patrick Lühne 2019-03-02 02:11:32 +01:00
parent 874752a395
commit cf9c899dab
Signed by: patrick
GPG Key ID: 05F3611E97A70ABF
2 changed files with 123 additions and 19 deletions

View File

@ -14,7 +14,7 @@ fn main()
{
pretty_env_logger::init();
let mut benchmark_repository = BenchmarkRepository::new("gitea@git.luehne.de:patrick/tplp-planning-benchmark.git", Path::new("cache").to_path_buf(), "gitea", "Potassco Bot", "bot@potassco.org");
let mut benchmark_repository = BenchmarkRepository::new("gitea@git.luehne.de:patrick/tplp-planning-benchmark.git", Path::new("cache").to_path_buf(), "gitea");
let content = benchmark_repository.read_file(Path::new("configurations.yml"), "config").unwrap();
let configurations = &YamlLoader::load_from_str(&content).unwrap()[0]["configurations"];

View File

@ -1,11 +1,11 @@
use git2::{Cred, Error, FetchOptions, Index, IndexEntry, IndexTime, Oid, Progress, PushOptions, RemoteCallbacks, Repository, Signature};
use git2::{Cred, Error, FetchOptions, Index, IndexEntry, IndexTime, Oid, Progress, PushOptions, RemoteCallbacks, Repository};
use indicatif::{ProgressBar, ProgressStyle};
use log::{info, trace};
use std::collections::{HashMap, HashSet};
use std::path::{Path, PathBuf};
use std::string::String;
use std::str;
use walkdir::WalkDir;
//use walkdir::WalkDir;
pub struct Job
{
@ -20,8 +20,6 @@ pub struct BenchmarkRepository
repository: Repository,
jobs: HashMap<u32, Job>,
ssh_user: String,
user_name: String,
user_email: String,
}
pub struct TargetPath
@ -127,7 +125,7 @@ impl BenchmarkRepository
repository
}
pub fn new(remote_url: &str, base_path: PathBuf, ssh_user: &str, user_name: &str, user_email: &str) -> BenchmarkRepository
pub fn new(remote_url: &str, base_path: PathBuf, ssh_user: &str) -> BenchmarkRepository
{
let repository = match Repository::open(&base_path)
{
@ -147,8 +145,6 @@ impl BenchmarkRepository
repository: repository,
jobs: HashMap::new(),
ssh_user: ssh_user.to_string(),
user_name: user_name.to_string(),
user_email: user_email.to_string(),
};
benchmark_repository
@ -160,17 +156,8 @@ impl BenchmarkRepository
benchmark_repository
}
pub fn read_file_as_index_entry(&self, file_path: &Path, result_file_path: &Path) -> IndexEntry
/*fn create_file_index_entry(&self, object_id: Oid, result_file_path: &Path) -> IndexEntry
{
// create a new blob with the file contents
let object_id = match self.repository.blob_path(file_path)
{
Ok(object_id) => object_id,
Err(error) => panic!("Could not write blob for “{}”: {}", file_path.display(), error),
};
info!("Created object “{}” from “{}”", object_id, file_path.display());
IndexEntry
{
ctime: IndexTime::new(0, 0),
@ -186,6 +173,39 @@ impl BenchmarkRepository
flags_extended: 0,
path: result_file_path.to_string_lossy().as_bytes().to_owned(),
}
}*/
fn create_directory_index_entry(&self, object_id: Oid, result_file_path: &Path) -> IndexEntry
{
IndexEntry
{
ctime: IndexTime::new(0, 0),
mtime: IndexTime::new(0, 0),
dev: 0,
ino: 0,
mode: 0o100755,
uid: 0,
gid: 0,
file_size: 0,
id: object_id,
flags: 0,
flags_extended: 0,
path: result_file_path.to_string_lossy().as_bytes().to_owned(),
}
}
/*fn read_file_as_index_entry(&self, file_path: &Path, result_file_path: &Path) -> IndexEntry
{
// create a new blob with the file contents
let object_id = match self.repository.blob_path(file_path)
{
Ok(object_id) => object_id,
Err(error) => panic!("Could not write blob for “{}”: {}", file_path.display(), error),
};
info!("Created object “{}” from “{}”", object_id, file_path.display());
self.create_file_index_entry(object_id, result_file_path)
}
pub fn commit_directory(&self, directory_path: &TargetPath, branch_name: &str)
@ -300,7 +320,7 @@ impl BenchmarkRepository
let mut remote = self.repository.find_remote("origin").expect("");
remote.push(&[&push_refspec], Some(&mut push_options)).expect("couldnt push");
}
}*/
pub fn file_exists(&self, file_path: &Path, branch_name: &str) -> bool
{
@ -418,6 +438,8 @@ impl BenchmarkRepository
info!("waiting for jobs to finish");
std::thread::sleep(std::time::Duration::from_secs(2));
let mut changed = false;
active_job_ids.retain
(
|job_id|
@ -444,6 +466,88 @@ impl BenchmarkRepository
Err(error) => panic!("could not access tip commit of “results” branch: {}", error),
};
let remote_tree = match remote_commit.tree()
{
Ok(value) => value,
Err(error) => panic!("could not access tip commit tree of “results” branch: {}", error),
};
let job_tree = match job_commit.tree()
{
Ok(value) => value,
Err(error) => panic!("cannot read results of job {}: {}", job_id, error),
};
let mut index = match Index::new()
{
Ok(value) => value,
Err(error) => panic!("could not create index: {}", error),
};
match index.read_tree(&remote_tree)
{
Ok(value) => value,
Err(error) => panic!("could not read tree into index: {}", error),
};
let result_path = Path::new(&job.key);
match index.add(&self.create_directory_index_entry(job_tree.id(), &result_path))
{
Ok(_) => (),
Err(error) => panic!("could not add results to index: {}", error),
};
let new_tree_object_id = match index.write_tree_to(&self.repository)
{
Ok(value) => value,
Err(error) => panic!("could not write index to tree: {}", error),
};
let new_tree = match self.repository.find_tree(new_tree_object_id)
{
Ok(value) => value,
Err(error) => panic!("could obtain tree: {}", error),
};
trace!("Created tree object “{}”", new_tree_object_id);
let author = job_commit.author();
let committer = job_commit.committer();
let message = job_commit.message().unwrap_or("");
let tip_reference_name = "refs/remotes/origin/results";
let commit_id = match self.repository.commit(Some(&tip_reference_name), &author, &committer, &message, &new_tree, &[&remote_commit])
{
Ok(value) => value,
Err(error) => panic!("could not write commit: {}", error),
};
let push_refspec = format!("refs/remotes/origin/results:refs/heads/results");
trace!("Created commit “{}”, using refspec “{}”", commit_id, push_refspec);
let mut remote_callbacks = RemoteCallbacks::new();
remote_callbacks.credentials(
|_, _, _|
{
match Cred::ssh_key_from_agent(&self.ssh_user)
{
Ok(value) => Ok(value),
Err(error) => panic!("could not retrieve key pair for SSH authentication as user “{}”: {}", self.ssh_user, error),
}
});
remote_callbacks.push_update_reference(
|reference, status| BenchmarkRepository::push_update_reference_callback(reference, status));
let mut push_options = PushOptions::new();
push_options.remote_callbacks(remote_callbacks);
let mut remote = self.repository.find_remote("origin").expect("");
remote.push(&[&push_refspec], Some(&mut push_options)).expect("couldnt push");
changed = true;
false
}
);