Autoschedule builds from trusted users
This commit is contained in:
parent
ac63df2a24
commit
5e4360e6af
|
@ -12,6 +12,20 @@ impl ACL {
|
|||
};
|
||||
}
|
||||
|
||||
pub fn build_job_destinations_for_user_repo(&self, user: &str, repo: &str)
|
||||
-> Vec<(Option<String>, Option<String>)> {
|
||||
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;
|
||||
|
|
|
@ -8,8 +8,37 @@ pub struct BuildJob {
|
|||
pub pr: Pr,
|
||||
pub subset: Option<Subset>,
|
||||
pub attrs: Vec<String>,
|
||||
pub logs: Option<(Option<String>, Option<String>)>, // (Exchange, Routing Key)
|
||||
pub statusreport: Option<(Option<String>, Option<String>)>, // (Exchange, Routing Key)
|
||||
pub logs: Option<ExchangeQueue>, // (Exchange, Routing Key)
|
||||
pub statusreport: Option<ExchangeQueue>, // (Exchange, Routing Key)
|
||||
}
|
||||
|
||||
pub type ExchangeQueue = (Option<Exchange>, Option<RoutingKey>);
|
||||
type Exchange = String;
|
||||
type RoutingKey = String;
|
||||
|
||||
impl BuildJob {
|
||||
pub fn new(repo: Repo,
|
||||
pr: Pr,
|
||||
subset: Subset,
|
||||
attrs: Vec<String>,
|
||||
logs: Option<ExchangeQueue>,
|
||||
statusreport: Option<ExchangeQueue>) -> 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<u8>) -> Result<BuildJob, serde_json::error::Error> {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,30 +53,13 @@ impl worker::SimpleWorker for GitHubCommentWorker {
|
|||
return vec![worker::Action::Ack];
|
||||
}
|
||||
|
||||
let build_destinations: Vec<(Option<String>, Option<String>)>;
|
||||
|
||||
if self.acl.can_build_unrestricted(
|
||||
let build_destinations = self.acl.build_job_destinations_for_user_repo(
|
||||
&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));
|
||||
|
|
|
@ -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<E> {
|
|||
cloner: checkout::CachedCloner,
|
||||
nix: Nix,
|
||||
github: hubcaps::Github,
|
||||
acl: ACL,
|
||||
identity: String,
|
||||
events: E,
|
||||
}
|
||||
|
@ -34,6 +37,7 @@ impl<E: stats::SysEvents> MassRebuildWorker<E> {
|
|||
cloner: checkout::CachedCloner,
|
||||
nix: Nix,
|
||||
github: hubcaps::Github,
|
||||
acl: ACL,
|
||||
identity: String,
|
||||
events: E,
|
||||
) -> MassRebuildWorker<E> {
|
||||
|
@ -41,6 +45,7 @@ impl<E: stats::SysEvents> MassRebuildWorker<E> {
|
|||
cloner: cloner,
|
||||
nix: nix.without_limited_supported_systems(),
|
||||
github: github,
|
||||
acl: acl,
|
||||
identity: identity,
|
||||
events: events,
|
||||
};
|
||||
|
@ -86,6 +91,8 @@ impl<E: stats::SysEvents> worker::SimpleWorker for MassRebuildWorker<E> {
|
|||
let gists = self.github.gists();
|
||||
let issue = repo.issue(job.pr.number);
|
||||
|
||||
let auto_schedule_build_archs: Option<Vec<buildjob::ExchangeQueue>>;
|
||||
|
||||
match issue.get() {
|
||||
Ok(iss) => {
|
||||
if iss.state == "closed" {
|
||||
|
@ -93,6 +100,11 @@ impl<E: stats::SysEvents> worker::SimpleWorker for MassRebuildWorker<E> {
|
|||
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<E: stats::SysEvents> worker::SimpleWorker for MassRebuildWorker<E> {
|
|||
})
|
||||
.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<E: stats::SysEvents> worker::SimpleWorker for MassRebuildWorker<E> {
|
|||
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<E: stats::SysEvents> worker::SimpleWorker for MassRebuildWorker<E> {
|
|||
);
|
||||
}
|
||||
|
||||
return self.actions().done(&job);
|
||||
return self.actions().done(&job, response);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue