Add an action to update jails automatically.
I probably will only use this for end-user systems like a laptop but not for servers so I can pick when I need to reboot my servers.
This commit is contained in:
parent
66823059b4
commit
5b8880252b
@ -5,6 +5,13 @@ CREATE TABLE IF NOT EXISTS global_action (
|
|||||||
next_run INTEGER DEFAULT 0 NOT NULL
|
next_run INTEGER DEFAULT 0 NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS jail_action (
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
jail_name TEXT NOT NULL,
|
||||||
|
next_run INTEGER DEFAULT 0 NOT NULL,
|
||||||
|
PRIMARY KEY (name, jail_name)
|
||||||
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS local_action (
|
CREATE TABLE IF NOT EXISTS local_action (
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
jail_name TEXT NOT NULL,
|
jail_name TEXT NOT NULL,
|
||||||
|
40
src/action/jail.rs
Normal file
40
src/action/jail.rs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
use std::process::Command;
|
||||||
|
use std::time::Duration;
|
||||||
|
use std::time::SystemTime;
|
||||||
|
|
||||||
|
use crate::action::ACTION_BUILD;
|
||||||
|
use crate::db::DbHandle;
|
||||||
|
use crate::db::DbJailAction;
|
||||||
|
|
||||||
|
pub(crate) const ACTION_UPDATE_JAIL: &str = "update_jail";
|
||||||
|
const ACTION_UPDATE_JAIL_INTERVAL: u64 = 604800;
|
||||||
|
|
||||||
|
pub(crate) fn update_jail(
|
||||||
|
db_conn: &mut DbHandle,
|
||||||
|
action: &DbJailAction,
|
||||||
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
println!("Updating jail {}.", action.jail_name.as_str());
|
||||||
|
Command::new("poudriere")
|
||||||
|
.arg("jail")
|
||||||
|
.arg("-j")
|
||||||
|
.arg(action.jail_name.as_str())
|
||||||
|
.arg("-u")
|
||||||
|
.status()?
|
||||||
|
.exit_ok()?;
|
||||||
|
let next_run = (SystemTime::now() + Duration::from_secs(ACTION_UPDATE_JAIL_INTERVAL))
|
||||||
|
.duration_since(SystemTime::UNIX_EPOCH)?
|
||||||
|
.as_secs();
|
||||||
|
|
||||||
|
let tx = db_conn.conn.transaction()?;
|
||||||
|
tx.execute(
|
||||||
|
"UPDATE jail_action SET next_run=$1 WHERE name=$2 AND jail_name=$3",
|
||||||
|
(next_run, ACTION_UPDATE_JAIL, action.jail_name.as_str()),
|
||||||
|
)?;
|
||||||
|
// Since we just updated the jail, force a build ASAP since it may need to rebuild everything.
|
||||||
|
tx.execute(
|
||||||
|
"UPDATE local_action SET next_run=0 WHERE name=$1 AND jail_name=$2",
|
||||||
|
(ACTION_BUILD, action.jail_name.as_str()),
|
||||||
|
)?;
|
||||||
|
tx.commit()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -1,10 +1,13 @@
|
|||||||
mod build;
|
mod build;
|
||||||
mod cleanup;
|
mod cleanup;
|
||||||
|
mod jail;
|
||||||
mod ports_tree;
|
mod ports_tree;
|
||||||
|
|
||||||
pub(crate) use build::build;
|
pub(crate) use build::build;
|
||||||
pub(crate) use build::ACTION_BUILD;
|
pub(crate) use build::ACTION_BUILD;
|
||||||
pub(crate) use cleanup::cleanup;
|
pub(crate) use cleanup::cleanup;
|
||||||
pub(crate) use cleanup::ACTION_CLEANUP;
|
pub(crate) use cleanup::ACTION_CLEANUP;
|
||||||
|
pub(crate) use jail::update_jail;
|
||||||
|
pub(crate) use jail::ACTION_UPDATE_JAIL;
|
||||||
pub(crate) use ports_tree::update_ports_tree;
|
pub(crate) use ports_tree::update_ports_tree;
|
||||||
pub(crate) use ports_tree::ACTION_UPDATE_PORTS_TREE;
|
pub(crate) use ports_tree::ACTION_UPDATE_PORTS_TREE;
|
||||||
|
@ -6,6 +6,7 @@ use rusqlite::params;
|
|||||||
use rusqlite::Connection;
|
use rusqlite::Connection;
|
||||||
|
|
||||||
use super::DbGlobalAction;
|
use super::DbGlobalAction;
|
||||||
|
use super::DbJailAction;
|
||||||
use super::DbLocalAction;
|
use super::DbLocalAction;
|
||||||
|
|
||||||
static DB_INIT_QUERY: &str = include_str!("../../migrations/01_init.sql");
|
static DB_INIT_QUERY: &str = include_str!("../../migrations/01_init.sql");
|
||||||
@ -43,6 +44,27 @@ impl DbHandle {
|
|||||||
Ok(rows)
|
Ok(rows)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_pending_jail_actions(
|
||||||
|
&mut self,
|
||||||
|
) -> Result<Vec<DbJailAction>, Box<dyn std::error::Error>> {
|
||||||
|
let now = SystemTime::now()
|
||||||
|
.duration_since(SystemTime::UNIX_EPOCH)?
|
||||||
|
.as_secs();
|
||||||
|
let mut stmt = self
|
||||||
|
.conn
|
||||||
|
.prepare("SELECT name, jail_name, next_run FROM jail_action WHERE next_run <= $1")?;
|
||||||
|
let rows = stmt
|
||||||
|
.query_map(params![now], |row| {
|
||||||
|
Ok(DbJailAction {
|
||||||
|
name: row.get(0)?,
|
||||||
|
jail_name: row.get(1)?,
|
||||||
|
next_run: row.get(2)?,
|
||||||
|
})
|
||||||
|
})?
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
Ok(rows)
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn get_pending_local_actions(
|
pub(crate) fn get_pending_local_actions(
|
||||||
&mut self,
|
&mut self,
|
||||||
) -> Result<Vec<DbLocalAction>, Box<dyn std::error::Error>> {
|
) -> Result<Vec<DbLocalAction>, Box<dyn std::error::Error>> {
|
||||||
@ -71,7 +93,7 @@ impl DbHandle {
|
|||||||
) -> Result<Duration, Box<dyn std::error::Error>> {
|
) -> Result<Duration, Box<dyn std::error::Error>> {
|
||||||
let now = SystemTime::now();
|
let now = SystemTime::now();
|
||||||
let mut stmt = self.conn.prepare(
|
let mut stmt = self.conn.prepare(
|
||||||
"WITH next_runs AS (SELECT next_run FROM global_action UNION SELECT next_run FROM local_action) SELECT next_run FROM next_runs ORDER BY next_run ASC",
|
"WITH next_runs AS (SELECT next_run FROM global_action UNION SELECT next_run FROM jail_action UNION SELECT next_run FROM local_action) SELECT min(next_run) FROM next_runs;",
|
||||||
)?;
|
)?;
|
||||||
let rows = stmt
|
let rows = stmt
|
||||||
.query_map(params![], |row| row.get(0))?
|
.query_map(params![], |row| row.get(0))?
|
||||||
|
@ -3,4 +3,5 @@ mod types;
|
|||||||
|
|
||||||
pub(crate) use init::DbHandle;
|
pub(crate) use init::DbHandle;
|
||||||
pub(crate) use types::DbGlobalAction;
|
pub(crate) use types::DbGlobalAction;
|
||||||
|
pub(crate) use types::DbJailAction;
|
||||||
pub(crate) use types::DbLocalAction;
|
pub(crate) use types::DbLocalAction;
|
||||||
|
@ -4,6 +4,13 @@ pub(crate) struct DbGlobalAction {
|
|||||||
pub(crate) next_run: i64,
|
pub(crate) next_run: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) struct DbJailAction {
|
||||||
|
pub(crate) name: String,
|
||||||
|
pub(crate) jail_name: String,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub(crate) next_run: i64,
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) struct DbLocalAction {
|
pub(crate) struct DbLocalAction {
|
||||||
pub(crate) name: String,
|
pub(crate) name: String,
|
||||||
pub(crate) jail_name: String,
|
pub(crate) jail_name: String,
|
||||||
|
13
src/main.rs
13
src/main.rs
@ -3,9 +3,11 @@ use std::{thread, time};
|
|||||||
|
|
||||||
use crate::action::build;
|
use crate::action::build;
|
||||||
use crate::action::cleanup;
|
use crate::action::cleanup;
|
||||||
|
use crate::action::update_jail;
|
||||||
use crate::action::update_ports_tree;
|
use crate::action::update_ports_tree;
|
||||||
use crate::action::ACTION_BUILD;
|
use crate::action::ACTION_BUILD;
|
||||||
use crate::action::ACTION_CLEANUP;
|
use crate::action::ACTION_CLEANUP;
|
||||||
|
use crate::action::ACTION_UPDATE_JAIL;
|
||||||
use crate::action::ACTION_UPDATE_PORTS_TREE;
|
use crate::action::ACTION_UPDATE_PORTS_TREE;
|
||||||
|
|
||||||
mod action;
|
mod action;
|
||||||
@ -32,6 +34,17 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for pending_jail_action in db_conn.get_pending_jail_actions()? {
|
||||||
|
match pending_jail_action.name.as_str() {
|
||||||
|
ACTION_UPDATE_JAIL => {
|
||||||
|
update_jail(&mut db_conn, &pending_jail_action)?;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
panic!("Unknown jail action: {}", pending_jail_action.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for pending_local_action in db_conn.get_pending_local_actions()? {
|
for pending_local_action in db_conn.get_pending_local_actions()? {
|
||||||
match pending_local_action.name.as_str() {
|
match pending_local_action.name.as_str() {
|
||||||
ACTION_BUILD => {
|
ACTION_BUILD => {
|
||||||
|
Loading…
Reference in New Issue
Block a user