Initial public release
This commit is contained in:
commit
c1107147b4
92 files changed
+10562
No files matched your search
@@ -0,0 +1,81 @@
|
||||
use std::time::Duration;
|
||||
use tracing::{info, error};
|
||||
use crate::db::Db;
|
||||
use crate::config::Config;
|
||||
use super::{log_job_start, log_job_end};
|
||||
|
||||
pub async fn run_backup_scheduler(db: Db, config: Config) {
|
||||
if !config.backup_enabled {
|
||||
info!("Background backup scheduler is disabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
info!("Starting background backup scheduler (interval: {} mins)...", config.backup_interval_mins);
|
||||
loop {
|
||||
// Run backup every configured interval
|
||||
tokio::time::sleep(Duration::from_secs(config.backup_interval_mins * 60)).await;
|
||||
info!("Running background database backup...");
|
||||
|
||||
let job_id = log_job_start(&db.system, "database_backup");
|
||||
match perform_backup(&db, &config).await {
|
||||
Ok(path) => {
|
||||
info!("Backup created successfully at {}", path);
|
||||
log_job_end(&db.system, &job_id, "success", None);
|
||||
}
|
||||
Err(e) => {
|
||||
let err_str = e.to_string();
|
||||
error!("Error performing backup: {}", err_str);
|
||||
log_job_end(&db.system, &job_id, "failed", Some(&err_str));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn perform_backup(db: &Db, config: &Config) -> Result<String, Box<dyn std::error::Error>> {
|
||||
use std::fs::File;
|
||||
use flate2::write::GzEncoder;
|
||||
use flate2::Compression;
|
||||
use tar::Builder;
|
||||
use chrono::Utc;
|
||||
use rusqlite::params;
|
||||
use uuid::Uuid;
|
||||
|
||||
let out_dir = config.backup_dir.clone();
|
||||
if !out_dir.exists() {
|
||||
std::fs::create_dir_all(&out_dir)?;
|
||||
}
|
||||
|
||||
let date_str = Utc::now().format("%Y-%m-%d-%H%M%S").to_string();
|
||||
let tar_name = format!("{}-bzod-backup.tar.gz", date_str);
|
||||
let tar_path = out_dir.join(tar_name);
|
||||
|
||||
let file = File::create(&tar_path)?;
|
||||
let enc = GzEncoder::new(file, Compression::default());
|
||||
let mut tar = Builder::new(enc);
|
||||
|
||||
let files = vec!["admin.db", "content.db", "analytics.db", "system.db"];
|
||||
for f in files {
|
||||
let db_file = config.data_dir.join(f);
|
||||
if db_file.exists() {
|
||||
tar.append_path_with_name(&db_file, f)?;
|
||||
}
|
||||
}
|
||||
|
||||
tar.into_inner()?.finish()?;
|
||||
let size_bytes = std::fs::metadata(&tar_path)?.len();
|
||||
let path_str = tar_path.to_string_lossy().to_string();
|
||||
|
||||
// Log to system.db.backup_history
|
||||
{
|
||||
let conn = db.system.lock().unwrap();
|
||||
let backup_id = Uuid::new_v4().to_string();
|
||||
let now = Utc::now().to_rfc3339();
|
||||
let _ = conn.execute(
|
||||
"INSERT INTO backup_history (id, backup_path, status, created_at, size_bytes, error_message)
|
||||
VALUES (?1, ?2, ?3, ?4, ?5, ?6);",
|
||||
params![backup_id, path_str, "success", now, size_bytes as i64, None::<String>],
|
||||
);
|
||||
}
|
||||
|
||||
Ok(path_str)
|
||||
}
|
||||
Reference in new issue
Block a user