diff --git a/ofborg/Cargo.lock b/ofborg/Cargo.lock index 38d63d3..147a2fb 100644 --- a/ofborg/Cargo.lock +++ b/ofborg/Cargo.lock @@ -1,3 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. [[package]] name = "aho-corasick" version = "0.5.3" @@ -245,7 +247,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "hubcaps" version = "0.3.16" -source = "git+https://github.com/grahamc/hubcaps.git#a7477f35f9dbc33a34f4486593f3725b4e523028" +source = "git+https://github.com/grahamc/hubcaps.git#1c5da1e60ee2d0d69188d83da048e7328aae05b9" dependencies = [ "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "frank_jwt 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ofborg/Cargo.toml b/ofborg/Cargo.toml index c87214d..c6e1063 100644 --- a/ofborg/Cargo.toml +++ b/ofborg/Cargo.toml @@ -20,7 +20,7 @@ serde_derive = "1.0" serde_json = "1.0" tempfile = "2.2.0" hubcaps = { git = "https://github.com/grahamc/hubcaps.git" } -#hubcaps = { path = "../hubcaps/" } # for testing patches +#hubcaps = { path = "../../../grahamc/hubcaps/" } # for testing patches hyper = "0.10.*" hyper-native-tls = "0.2.4" lru-cache = "0.1.1" diff --git a/ofborg/src/bin/github-comment-poster.rs b/ofborg/src/bin/github-comment-poster.rs index 07fbb83..3c93a1e 100644 --- a/ofborg/src/bin/github-comment-poster.rs +++ b/ofborg/src/bin/github-comment-poster.rs @@ -62,7 +62,7 @@ fn main() { channel .consume( worker::new(tasks::githubcommentposter::GitHubCommentPoster::new( - cfg.github_app(), + cfg.github_app_vendingmachine(), )), easyamqp::ConsumeConfig { queue: "build-results".to_owned(), diff --git a/ofborg/src/config.rs b/ofborg/src/config.rs index cb4a881..0854743 100644 --- a/ofborg/src/config.rs +++ b/ofborg/src/config.rs @@ -3,14 +3,13 @@ use hyper::net::HttpsConnector; use hyper::Client; use hyper_native_tls::NativeTlsClient; use nix::Nix; +use ofborg::acl; use serde_json; use std::collections::HashMap; use std::fs::File; use std::io::Read; use std::path::{Path, PathBuf}; -use ofborg::acl; - #[derive(Serialize, Deserialize, Debug)] pub struct Config { pub runner: RunnerConfig, @@ -115,17 +114,12 @@ impl Config { ) } - pub fn github_app(&self) -> Github { - let conf = self.github_app.clone().unwrap(); - Github::new( - "github.com/grahamc/ofborg (app)", - // tls configured hyper client - Client::with_connector(HttpsConnector::new(NativeTlsClient::new().unwrap())), - Credentials::InstallationToken(InstallationTokenGenerator::new( - conf.installation_id, - JWTCredentials::new(conf.app_id, conf.private_key), - )), - ) + pub fn github_app_vendingmachine(&self) -> GithubAppVendingMachine { + GithubAppVendingMachine { + conf: self.github_app.clone().unwrap(), + id_cache: HashMap::new(), + client_cache: HashMap::new(), + } } pub fn nix(&self) -> Nix { @@ -169,3 +163,61 @@ pub fn load(filename: &Path) -> Config { deserialized } + +pub struct GithubAppVendingMachine { + conf: GithubAppConfig, + id_cache: HashMap<(String, String), Option>, + client_cache: HashMap, +} + +impl GithubAppVendingMachine { + fn useragent(&self) -> &'static str { + "github.com/grahamc/ofborg (app)" + } + + fn jwt(&self) -> JWTCredentials { + JWTCredentials::new(self.conf.app_id, self.conf.private_key.clone()) + } + + fn install_id_for_repo(&mut self, owner: &str, repo: &str) -> Option { + let useragent = self.useragent(); + let jwt = self.jwt(); + + let key = (owner.to_owned(), repo.to_owned()); + + *self.id_cache.entry(key).or_insert_with(|| { + info!("Looking up install ID for {}/{}", owner, repo); + + let lookup_gh = Github::new( + useragent, + Client::with_connector(HttpsConnector::new(NativeTlsClient::new().unwrap())), + Credentials::JWT(jwt), + ); + + match lookup_gh.app().find_repo_installation(owner, repo) { + Ok(install_id) => { + debug!("Received install ID {:#?}", install_id); + Some(install_id.id) + } + Err(e) => { + warn!("Error during install ID lookup: {:#?}", e); + None + } + } + }) + } + + pub fn for_repo<'a>(&'a mut self, owner: &str, repo: &str) -> Option<&'a Github> { + let useragent = self.useragent(); + let jwt = self.jwt(); + let install_id = self.install_id_for_repo(owner, repo)?; + + Some(self.client_cache.entry(install_id).or_insert_with(|| { + Github::new( + useragent, + Client::with_connector(HttpsConnector::new(NativeTlsClient::new().unwrap())), + Credentials::InstallationToken(InstallationTokenGenerator::new(install_id, jwt)), + ) + })) + } +} diff --git a/ofborg/src/tasks/evaluate.rs b/ofborg/src/tasks/evaluate.rs index 3b3f236..895b455 100644 --- a/ofborg/src/tasks/evaluate.rs +++ b/ofborg/src/tasks/evaluate.rs @@ -313,6 +313,7 @@ impl worker::SimpleWorker for EvaluationWorker }) .all(|status| status == Ok(())); + info!("Finished evaluations"); let mut response: worker::Actions = vec![]; if eval_results { @@ -320,6 +321,10 @@ impl worker::SimpleWorker for EvaluationWorker .all_evaluations_passed(&Path::new(&refpath), &mut overall_status); match ret { Ok(builds) => { + info!( + "Scheduling build jobs {:#?} on arches {:#?}", + builds, auto_schedule_build_archs + ); for buildjob in builds { for arch in auto_schedule_build_archs.iter() { let (exchange, routingkey) = arch.as_build_destination(); @@ -341,6 +346,7 @@ impl worker::SimpleWorker for EvaluationWorker } } Err(e) => { + info!("Failed after all the evaluations passed"); if self .handle_strategy_err(Err(e), &gists, &mut overall_status) .is_err() @@ -350,6 +356,8 @@ impl worker::SimpleWorker for EvaluationWorker } } + info!("Just about done..."); + overall_status.set_with_description("^.^!", hubcaps::statuses::State::Success); } else { overall_status @@ -358,6 +366,7 @@ impl worker::SimpleWorker for EvaluationWorker self.events.notify(Event::TaskEvaluationCheckComplete); + info!("done!"); self.actions().done(&job, response) } } diff --git a/ofborg/src/tasks/githubcommentposter.rs b/ofborg/src/tasks/githubcommentposter.rs index 9cae3ed..34871a7 100644 --- a/ofborg/src/tasks/githubcommentposter.rs +++ b/ofborg/src/tasks/githubcommentposter.rs @@ -5,20 +5,20 @@ use serde_json; use amqp::protocol::basic::{BasicProperties, Deliver}; use chrono::{DateTime, Utc}; -use hubcaps; use hubcaps::checks::{CheckRunOptions, CheckRunState, Conclusion, Output}; use message::buildjob::{BuildJob, QueuedBuildJobs}; +use ofborg::config::GithubAppVendingMachine; use ofborg::message::buildresult::{BuildResult, BuildStatus, LegacyBuildResult}; use ofborg::message::Repo; use ofborg::worker; pub struct GitHubCommentPoster { - github: hubcaps::Github, + github_vend: GithubAppVendingMachine, } impl GitHubCommentPoster { - pub fn new(github: hubcaps::Github) -> GitHubCommentPoster { - GitHubCommentPoster { github } + pub fn new(github_vend: GithubAppVendingMachine) -> GitHubCommentPoster { + GitHubCommentPoster { github_vend } } } @@ -77,7 +77,9 @@ impl worker::SimpleWorker for GitHubCommentPoster { println!(":{:?}", check); let check_create_attempt = self - .github + .github_vend + .for_repo(&repo.owner, &repo.name) + .unwrap() .repo(repo.owner.clone(), repo.name.clone()) .checkruns() .create(&check);