From 5e4360e6af780e6cb82271cea16a1fc9ce0759c0 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Thu, 1 Feb 2018 21:30:23 -0500 Subject: [PATCH] Autoschedule builds from trusted users --- ofborg/src/acl.rs | 14 ++++++++ ofborg/src/message/buildjob.rs | 33 +++++++++++++++-- ofborg/src/message/massrebuildjob.rs | 5 +-- ofborg/src/tasks/githubcommentfilter.rs | 48 +++++++------------------ ofborg/src/tasks/massrebuilder.rs | 31 ++++++++++++++-- 5 files changed, 89 insertions(+), 42 deletions(-) diff --git a/ofborg/src/acl.rs b/ofborg/src/acl.rs index f1a9d3e..66e8d83 100644 --- a/ofborg/src/acl.rs +++ b/ofborg/src/acl.rs @@ -12,6 +12,20 @@ impl ACL { }; } + pub fn build_job_destinations_for_user_repo(&self, user: &str, repo: &str) + -> Vec<(Option, Option)> { + if self.can_build_unrestricted(user, repo) { + vec![(Some("build-jobs".to_owned()), None)] + } else if self.can_build_restricted(user, repo) { + vec![ + (None, Some("build-inputs-x86_64-linux".to_owned())), + (None, Some("build-inputs-aarch64-linux".to_owned())), + ] + } else { + vec![] + } + } + pub fn can_build_restricted(&self, user: &str, repo: &str) -> bool { if repo.to_lowercase() != "nixos/nixpkgs" { return false; diff --git a/ofborg/src/message/buildjob.rs b/ofborg/src/message/buildjob.rs index 81599fe..9930af8 100644 --- a/ofborg/src/message/buildjob.rs +++ b/ofborg/src/message/buildjob.rs @@ -8,8 +8,37 @@ pub struct BuildJob { pub pr: Pr, pub subset: Option, pub attrs: Vec, - pub logs: Option<(Option, Option)>, // (Exchange, Routing Key) - pub statusreport: Option<(Option, Option)>, // (Exchange, Routing Key) + pub logs: Option, // (Exchange, Routing Key) + pub statusreport: Option, // (Exchange, Routing Key) +} + +pub type ExchangeQueue = (Option, Option); +type Exchange = String; +type RoutingKey = String; + +impl BuildJob { + pub fn new(repo: Repo, + pr: Pr, + subset: Subset, + attrs: Vec, + logs: Option, + statusreport: Option) -> BuildJob { + + let logbackrk = format!( + "{}.{}", + repo.full_name.clone(), + pr.number, + ).to_lowercase(); + + BuildJob { + repo: repo, + pr: pr, + subset: Some(subset), + attrs: attrs, + logs: Some(logs.unwrap_or((Some("logs".to_owned()), Some(logbackrk)))), + statusreport: Some(statusreport.unwrap_or((Some("build-results".to_owned()), None))), + } + } } pub fn from(data: &Vec) -> Result { diff --git a/ofborg/src/message/massrebuildjob.rs b/ofborg/src/message/massrebuildjob.rs index a486bca..ae109a1 100644 --- a/ofborg/src/message/massrebuildjob.rs +++ b/ofborg/src/message/massrebuildjob.rs @@ -20,7 +20,8 @@ impl Actions { return vec![worker::Action::Ack]; } - pub fn done(&mut self, _job: &MassRebuildJob) -> worker::Actions { - return vec![worker::Action::Ack]; + pub fn done(&mut self, _job: &MassRebuildJob, mut response: worker::Actions) -> worker::Actions { + response.push(worker::Action::Ack); + return response; } } diff --git a/ofborg/src/tasks/githubcommentfilter.rs b/ofborg/src/tasks/githubcommentfilter.rs index 55c54c8..5e3fa31 100644 --- a/ofborg/src/tasks/githubcommentfilter.rs +++ b/ofborg/src/tasks/githubcommentfilter.rs @@ -53,30 +53,13 @@ impl worker::SimpleWorker for GitHubCommentWorker { return vec![worker::Action::Ack]; } - let build_destinations: Vec<(Option, Option)>; + let build_destinations = self.acl.build_job_destinations_for_user_repo( + &job.comment.user.login, + &job.repository.full_name, + ); - if self.acl.can_build_unrestricted( - &job.comment.user.login, - &job.repository.full_name, - ) - { - build_destinations = vec![(Some("build-jobs".to_owned()), None)]; - } else if self.acl.can_build_restricted( - &job.comment.user.login, - &job.repository.full_name, - ) - { - build_destinations = vec![ - (None, Some("build-inputs-x86_64-linux".to_owned())), - (None, Some("build-inputs-aarch64-linux".to_owned())), - ]; - } else { - println!( - "ACL prohibits {} from building {:?} for {}", - job.comment.user.login, - instructions, - job.repository.full_name - ); + if build_destinations.len() == 0 { + // Don't process comments if they can't build anything return vec![worker::Action::Ack]; } @@ -124,19 +107,14 @@ impl worker::SimpleWorker for GitHubCommentWorker { for instruction in instructions { match instruction { commentparser::Instruction::Build(subset, attrs) => { - let logbackrk = format!( - "{}.{}", - job.repository.full_name.clone(), - job.issue.number.clone() + let msg = buildjob::BuildJob::new( + repo_msg.clone(), + pr_msg.clone(), + subset, + attrs, + None, + None ); - let msg = buildjob::BuildJob { - repo: repo_msg.clone(), - pr: pr_msg.clone(), - subset: Some(subset), - attrs: attrs, - logs: Some((Some("logs".to_owned()), Some(logbackrk.to_lowercase()))), - statusreport: Some((Some("build-results".to_owned()), None)), - }; for (exch, rk) in build_destinations.clone() { response.push(worker::publish_serde_action(exch, rk, &msg)); diff --git a/ofborg/src/tasks/massrebuilder.rs b/ofborg/src/tasks/massrebuilder.rs index 23c726a..c9500ba 100644 --- a/ofborg/src/tasks/massrebuilder.rs +++ b/ofborg/src/tasks/massrebuilder.rs @@ -9,15 +9,17 @@ use std::io::BufReader; use std::path::Path; use std::path::PathBuf; use ofborg::checkout; -use ofborg::message::massrebuildjob; +use ofborg::message::{massrebuildjob, buildjob}; use ofborg::nix::Nix; +use ofborg::acl::ACL; use ofborg::stats; use ofborg::worker; use ofborg::tagger::{StdenvTagger, RebuildTagger}; use ofborg::outpathdiff::{OutPaths, OutPathDiff}; use ofborg::evalchecker::EvalChecker; use ofborg::commitstatus::CommitStatus; +use ofborg::commentparser::Subset; use amqp::protocol::basic::{Deliver, BasicProperties}; use hubcaps; @@ -25,6 +27,7 @@ pub struct MassRebuildWorker { cloner: checkout::CachedCloner, nix: Nix, github: hubcaps::Github, + acl: ACL, identity: String, events: E, } @@ -34,6 +37,7 @@ impl MassRebuildWorker { cloner: checkout::CachedCloner, nix: Nix, github: hubcaps::Github, + acl: ACL, identity: String, events: E, ) -> MassRebuildWorker { @@ -41,6 +45,7 @@ impl MassRebuildWorker { cloner: cloner, nix: nix.without_limited_supported_systems(), github: github, + acl: acl, identity: identity, events: events, }; @@ -86,6 +91,8 @@ impl worker::SimpleWorker for MassRebuildWorker { let gists = self.github.gists(); let issue = repo.issue(job.pr.number); + let auto_schedule_build_archs: Option>; + match issue.get() { Ok(iss) => { if iss.state == "closed" { @@ -93,6 +100,11 @@ impl worker::SimpleWorker for MassRebuildWorker { info!("Skipping {} because it is closed", job.pr.number); return self.actions().skip(&job); } + + auto_schedule_build_archs = Some(self.acl.build_job_destinations_for_user_repo( + &iss.user.login, + &job.repo.full_name, + )); } Err(e) => { self.events.tick("issue-fetch-failed"); @@ -345,6 +357,9 @@ impl worker::SimpleWorker for MassRebuildWorker { }) .all(|status| status == Ok(())); + + let mut response: worker::Actions = vec![]; + if eval_results { let mut status = CommitStatus::new( repo.statuses(), @@ -375,7 +390,17 @@ impl worker::SimpleWorker for MassRebuildWorker { try_build.sort(); try_build.dedup(); - println!("try to build: {:?}", try_build); + let msg = buildjob::BuildJob::new( + job.repo.clone(), + job.pr.clone(), + Subset::Nixpkgs, + try_build, + None, + None, + ); + for (dest, rk) in auto_schedule_build_archs.unwrap_or(vec![]) { + response.push(worker::publish_serde_action(dest, rk, &msg)); + } } Err(mut out) => { eval_results = false; @@ -428,7 +453,7 @@ impl worker::SimpleWorker for MassRebuildWorker { ); } - return self.actions().done(&job); + return self.actions().done(&job, response); } }