diff --git a/migrations/01_init.sql b/migrations/01_init.sql index bffce00..6f1280d 100644 --- a/migrations/01_init.sql +++ b/migrations/01_init.sql @@ -6,9 +6,10 @@ CREATE TABLE IF NOT EXISTS global_action ( ); CREATE TABLE IF NOT EXISTS local_action ( + name TEXT NOT NULL, jail_name TEXT NOT NULL, tree TEXT NOT NULL, set_name TEXT NOT NULL, next_run INTEGER DEFAULT 0 NOT NULL, - PRIMARY KEY (jail_name, tree, set_name) + PRIMARY KEY (name, jail_name, tree, set_name) ); diff --git a/src/action/build.rs b/src/action/build.rs new file mode 100644 index 0000000..bca6e0f --- /dev/null +++ b/src/action/build.rs @@ -0,0 +1,71 @@ +use std::process::Command; +use std::time::Duration; +use std::time::SystemTime; + +use crate::db::DbHandle; +use crate::db::DbLocalAction; + +pub(crate) const ACTION_BUILD: &str = "build"; +const ACTION_BUILD_INTERVAL: u64 = 1209600; +const ACTION_BUILD_JOBS: u64 = 1; + +pub(crate) fn build( + db_conn: &mut DbHandle, + action: &DbLocalAction, +) -> Result<(), Box> { + println!( + "Performing build for jail {} tree {} set {}.", + action.jail_name.as_str(), + action.tree.as_str(), + action.set_name.as_str() + ); + Command::new("poudriere") + .arg("pkgclean") + .arg("-v") + .arg("-y") + .arg("-j") + .arg(action.jail_name.as_str()) + .arg("-p") + .arg(action.tree.as_str()) + .arg("-z") + .arg(action.set_name.as_str()) + .arg("-f") + .arg(format!( + "/usr/local/etc/poudriere.d/{}-{}-{}-pkglist", + action.jail_name.as_str(), + action.tree.as_str(), + action.set_name.as_str() + )) + .status()? + .exit_ok()?; + Command::new("poudriere") + .arg("bulk") + .arg("-J") + .arg(ACTION_BUILD_JOBS.to_string()) + .arg("-j") + .arg(action.jail_name.as_str()) + .arg("-p") + .arg(action.tree.as_str()) + .arg("-z") + .arg(action.set_name.as_str()) + .arg("-f") + .arg(format!( + "/usr/local/etc/poudriere.d/{}-{}-{}-pkglist", + action.jail_name.as_str(), + action.tree.as_str(), + action.set_name.as_str() + )) + .status()? + .exit_ok()?; + let next_run = (SystemTime::now() + Duration::from_secs(ACTION_BUILD_INTERVAL)) + .duration_since(SystemTime::UNIX_EPOCH)? + .as_secs(); + + let tx = db_conn.conn.transaction()?; + tx.execute( + "UPDATE local_action SET next_run=$1 WHERE name=$2 AND jail_name=$3 AND tree=$4 AND set_name=$5", + (next_run, ACTION_BUILD, action.jail_name.as_str(), action.tree.as_str(), action.set_name.as_str()), + )?; + tx.commit()?; + Ok(()) +} diff --git a/src/action/mod.rs b/src/action/mod.rs index 72c2de7..9c831b1 100644 --- a/src/action/mod.rs +++ b/src/action/mod.rs @@ -1,5 +1,10 @@ +mod build; mod cleanup; mod ports_tree; +pub(crate) use build::build; +pub(crate) use build::ACTION_BUILD; pub(crate) use cleanup::cleanup; +pub(crate) use cleanup::ACTION_CLEANUP; pub(crate) use ports_tree::update_ports_tree; +pub(crate) use ports_tree::ACTION_UPDATE_PORTS_TREE; diff --git a/src/db/init.rs b/src/db/init.rs index a0a3629..28dce2a 100644 --- a/src/db/init.rs +++ b/src/db/init.rs @@ -50,15 +50,16 @@ impl DbHandle { .duration_since(SystemTime::UNIX_EPOCH)? .as_secs(); let mut stmt = self.conn.prepare( - "SELECT jail_name, tree, set_name, next_run FROM local_action WHERE next_run <= $1", + "SELECT name, jail_name, tree, set_name, next_run FROM local_action WHERE next_run <= $1", )?; let rows = stmt .query_map(params![now], |row| { Ok(DbLocalAction { - jail_name: row.get(0)?, - tree: row.get(1)?, - set_name: row.get(2)?, - next_run: row.get(3)?, + name: row.get(0)?, + jail_name: row.get(1)?, + tree: row.get(2)?, + set_name: row.get(3)?, + next_run: row.get(4)?, }) })? .collect::, _>>()?; diff --git a/src/db/types.rs b/src/db/types.rs index 1454aed..c610ba4 100644 --- a/src/db/types.rs +++ b/src/db/types.rs @@ -4,6 +4,7 @@ pub(crate) struct DbGlobalAction { } pub(crate) struct DbLocalAction { + pub(crate) name: String, pub(crate) jail_name: String, pub(crate) tree: String, pub(crate) set_name: String, diff --git a/src/main.rs b/src/main.rs index 5674081..a188a1b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,12 @@ #![feature(exit_status_error)] use std::{thread, time}; +use crate::action::build; use crate::action::cleanup; use crate::action::update_ports_tree; +use crate::action::ACTION_BUILD; +use crate::action::ACTION_CLEANUP; +use crate::action::ACTION_UPDATE_PORTS_TREE; mod action; mod db; @@ -28,7 +32,16 @@ fn main() -> Result<(), Box> { }; } - let pending_local_actions = db_conn.get_pending_local_actions()?; + for pending_local_action in db_conn.get_pending_local_actions()? { + match pending_local_action.name.as_str() { + ACTION_BUILD => { + build(&mut db_conn, &pending_local_action)?; + } + _ => { + panic!("Unknown local action: {}", pending_local_action.name); + } + } + } let time_until_next_action = db_conn.get_time_until_next_action()?; let sleep_duration = std::cmp::min(