Skip to content

Commit

Permalink
feat: initial support for reading ENVREQ
Browse files Browse the repository at this point in the history
  • Loading branch information
jiegec committed Mar 21, 2024
1 parent 6e73f0f commit 5cd696a
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 11 deletions.
78 changes: 77 additions & 1 deletion buildit-utils/src/github.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use jsonwebtoken::EncodingKey;
use octocrab::{models::pulls::PullRequest, params};
use std::{
borrow::Cow,
collections::{HashMap, HashSet},
collections::{BTreeMap, HashMap, HashSet},
fs,
io::{BufRead, BufReader},
path::{Path, PathBuf},
Expand Down Expand Up @@ -857,6 +857,82 @@ pub fn resolve_packages(pkgs: &[String], p: &Path) -> anyhow::Result<Vec<String>
Ok(req_pkgs)
}

#[derive(Debug, Clone, Copy, Default)]
pub struct EnvironmentRequirement {
pub min_core: Option<i32>,
pub min_total_mem: Option<i64>,
pub min_total_mem_per_core: Option<f32>,
pub min_disk: Option<i64>,
}

/// `packages` should have no groups nor modifiers
/// Return one ENVREQ for each arch
#[tracing::instrument(skip(p))]
pub fn get_environment_requirement(
p: &Path,
packages: &[String],
) -> BTreeMap<&'static str, EnvironmentRequirement> {
let mut res = BTreeMap::new();

for_each_abbs(p, |pkg, path| {
if !packages.contains(&pkg.to_string()) {
return;
}

let spec = path.join("spec");
let spec = std::fs::read_to_string(spec);

if let Ok(spec) = spec {
let spec = read_ab_with_apml(&spec);
for arch in ALL_ARCH {
let res_arch: &mut EnvironmentRequirement = res.entry(*arch).or_default();
if let Some(env_req) = spec
.get(&format!("ENV_REQ__{arch}"))
.or_else(|| spec.get("ENV_REQ"))
{
for req in env_req.split(" ") {
if let Some((key, value)) = req.split_once("=") {
let val = value.parse::<f32>();
match (key, val) {
("core", Ok(val)) => {
*res_arch.min_core.get_or_insert(0) =
std::cmp::max(res_arch.min_core.unwrap_or(0), val as i32);
}
("total_mem", Ok(val)) => {
// unit: GiB -> B
*res_arch.min_total_mem.get_or_insert(0) = std::cmp::max(
res_arch.min_total_mem.unwrap_or(0),
(val as i64) * 1024 * 1024 * 1024,
);
}
("total_mem_per_core", Ok(val)) => {
// unit: GiB
*res_arch.min_total_mem_per_core.get_or_insert(0.0) = f32::max(
res_arch.min_total_mem_per_core.unwrap_or(0.0),
val * 1024.0 * 1024.0 * 1024.0,
);
}
("disk", Ok(val)) => {
// unit: GB -> B
*res_arch.min_disk.get_or_insert(0) = std::cmp::max(
res_arch.min_disk.unwrap_or(0),
(val as i64) * 1000 * 1000 * 1000,
);
}
_ => {
warn!("Unsupported environment requirement: {}", req);
}
}
}
}
}
}
}
});

res
}

#[test]
fn test_get_archs() {
let binding = ["autobuild3".to_owned(), "autobuild4".to_owned()];
Expand Down
25 changes: 20 additions & 5 deletions server/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ use crate::{
};
use anyhow::anyhow;
use anyhow::Context;
use buildit_utils::github::{get_archs, resolve_packages, update_abbs};
use buildit_utils::github::{
get_archs, get_environment_requirement, resolve_packages, update_abbs,
};
use diesel::{
dsl::count, ExpressionMethods, OptionalExtension, QueryDsl, RunQueryDsl, SelectableHelper,
};
Expand Down Expand Up @@ -98,6 +100,18 @@ pub async fn pipeline_new(
String::from_utf8_lossy(&output.stdout).trim().to_string()
}
};

// find environment requirements
let resolved_pkgs = resolve_packages(
&packages
.split(",")
.map(|s| s.to_string())
.collect::<Vec<String>>(),
&ARGS.abbs_path,
)
.context("Resolve packages")?;
let env_req = get_environment_requirement(&ARGS.abbs_path, &resolved_pkgs);

// create a new pipeline
let mut conn = pool
.get()
Expand Down Expand Up @@ -169,17 +183,18 @@ pub async fn pipeline_new(

// create a new job
use crate::schema::jobs;
let env_req_current = env_req.get(*arch).cloned().unwrap_or_default();
let new_job = NewJob {
pipeline_id: pipeline.id,
packages: packages.to_string(),
arch: arch.to_string(),
creation_time: chrono::Utc::now(),
status: "created".to_string(),
github_check_run_id: github_check_run_id.map(|id| id as i64),
require_min_core: None,
require_min_total_mem: None,
require_min_total_mem_per_core: None,
require_min_disk: None,
require_min_core: env_req_current.min_core,
require_min_total_mem: env_req_current.min_total_mem,
require_min_total_mem_per_core: env_req_current.min_total_mem_per_core,
require_min_disk: env_req_current.min_disk,
};
diesel::insert_into(jobs::table)
.values(&new_job)
Expand Down
5 changes: 0 additions & 5 deletions server/src/bot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,11 +381,6 @@ pub async fn answer(bot: Bot, msg: Message, cmd: Command, pool: DbPool) -> Respo
None
};

let pkgs = parts[2]
.split(',')
.map(|x| x.to_string())
.collect::<Vec<_>>();

let archs = if parts.len() == 5 {
let archs = parts[4].split(',').collect::<Vec<_>>();
Some(handle_archs_args(archs))
Expand Down

0 comments on commit 5cd696a

Please sign in to comment.