generalbots/src/core/bootstrap/bootstrap_manager.rs
Rodrigo Rodriguez 5ea171d126
Some checks failed
BotServer CI / build (push) Failing after 1m34s
Refactor: Split large files into modular subdirectories
Split 20+ files over 1000 lines into focused subdirectories for better
maintainability and code organization. All changes maintain backward
compatibility through re-export wrappers.

Major splits:
- attendance/llm_assist.rs (2074→7 modules)
- basic/keywords/face_api.rs → face_api/ (7 modules)
- basic/keywords/file_operations.rs → file_ops/ (8 modules)
- basic/keywords/hear_talk.rs → hearing/ (6 modules)
- channels/wechat.rs → wechat/ (10 modules)
- channels/youtube.rs → youtube/ (5 modules)
- contacts/mod.rs → contacts_api/ (6 modules)
- core/bootstrap/mod.rs → bootstrap/ (5 modules)
- core/shared/admin.rs → admin_*.rs (5 modules)
- designer/canvas.rs → canvas_api/ (6 modules)
- designer/mod.rs → designer_api/ (6 modules)
- docs/handlers.rs → handlers_api/ (11 modules)
- drive/mod.rs → drive_handlers.rs, drive_types.rs
- learn/mod.rs → types.rs
- main.rs → main_module/ (7 modules)
- meet/webinar.rs → webinar_api/ (8 modules)
- paper/mod.rs → (10 modules)
- security/auth.rs → auth_api/ (7 modules)
- security/passkey.rs → (4 modules)
- sources/mod.rs → sources_api/ (5 modules)
- tasks/mod.rs → task_api/ (5 modules)

Stats: 38,040 deletions, 1,315 additions across 318 files

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-12 21:09:30 +00:00

180 lines
5.8 KiB
Rust

// Bootstrap manager implementation
use crate::core::bootstrap::bootstrap_types::{BootstrapManager, BootstrapProgress};
use crate::core::bootstrap::bootstrap_utils::{safe_pkill, safe_pgrep, safe_sh_command, safe_curl, safe_fuser, dump_all_component_logs, vault_health_check};
use crate::core::config::AppConfig;
use crate::core::package_manager::{PackageManager, InstallMode};
use anyhow::Result;
use chrono::Utc;
use log::{debug, error, info, warn};
use rand::distr::Alphanumeric;
use std::path::PathBuf;
use std::process::Command;
use tokio::time::{sleep, Duration};
use uuid::Uuid;
impl BootstrapManager {
pub fn new(mode: InstallMode, tenant: Option<String>) -> Self {
let stack_path = std::env::var("BOTSERVER_STACK_PATH")
.map(PathBuf::from)
.unwrap_or_else(|_| PathBuf::from("./botserver-stack"));
Self {
install_mode: mode,
tenant,
stack_path,
}
}
pub fn stack_dir(&self, subpath: &str) -> PathBuf {
self.stack_path.join(subpath)
}
pub fn vault_bin(&self) -> String {
self.stack_dir("bin/vault/vault")
.to_str()
.unwrap_or("./botserver-stack/bin/vault/vault")
.to_string()
}
pub async fn kill_stack_processes(&self) -> Result<()> {
info!("Killing any existing stack processes...");
let processes = crate::core::bootstrap::bootstrap_utils::get_processes_to_kill();
for (name, args) in processes {
// safe_pkill expects &[&str] for pattern, so convert the name
safe_pkill(&[name], &args);
}
// Give processes time to terminate
sleep(Duration::from_millis(500)).await;
info!("Stack processes terminated");
Ok(())
}
pub async fn start_all(&mut self) -> Result<()> {
let pm = PackageManager::new(self.install_mode.clone(), self.tenant.clone())?;
info!("Starting bootstrap process...");
if pm.is_installed("vault") {
let vault_already_running = vault_health_check();
if vault_already_running {
info!("Vault is already running");
} else {
info!("Starting Vault secrets service...");
match pm.start("vault") {
Ok(_child) => {
info!("Vault process started, waiting for initialization...");
// Wait for vault to be ready
for i in 0..10 {
sleep(Duration::from_secs(1)).await;
if vault_health_check() {
info!("Vault is responding");
break;
}
}
}
Err(e) => {
warn!("Vault might already be running: {}", e);
}
}
}
}
if pm.is_installed("vector_db") {
info!("Starting Vector database...");
match pm.start("vector_db") {
Ok(_child) => {
info!("Vector database started");
}
Err(e) => {
warn!("Failed to start Vector database: {}", e);
}
}
}
if pm.is_installed("postgres") {
info!("Starting PostgreSQL...");
match pm.start("postgres") {
Ok(_child) => {
info!("PostgreSQL started");
}
Err(e) => {
warn!("Failed to start PostgreSQL: {}", e);
}
}
}
if pm.is_installed("redis") {
info!("Starting Redis...");
match pm.start("redis") {
Ok(_child) => {
info!("Redis started");
}
Err(e) => {
warn!("Failed to start Redis: {}", e);
}
}
}
if pm.is_installed("minio") {
info!("Starting MinIO...");
match pm.start("minio") {
Ok(_child) => {
info!("MinIO started");
}
Err(e) => {
warn!("Failed to start MinIO: {}", e);
}
}
}
// Caddy is the web server
match Command::new("caddy")
.arg("validate")
.arg("--config")
.arg("/etc/caddy/Caddyfile")
.output()
{
Ok(_) => info!("Caddy configuration is valid"),
Err(e) => {
warn!("Caddy configuration error: {:?}", e);
}
}
info!("Bootstrap process completed!");
Ok(())
}
/// Check system status
pub fn system_status(&self) -> BootstrapProgress {
BootstrapProgress::StartingComponent("System".to_string())
}
/// Run the bootstrap process
pub async fn bootstrap(&mut self) -> Result<()> {
info!("Starting bootstrap process...");
// Kill any existing processes
self.kill_stack_processes().await?;
Ok(())
}
/// Sync templates to database
pub fn sync_templates_to_database(&self) -> Result<()> {
info!("Syncing templates to database...");
// TODO: Implement actual template sync
Ok(())
}
/// Upload templates to drive
pub async fn upload_templates_to_drive(&self, _cfg: &AppConfig) -> Result<()> {
info!("Uploading templates to drive...");
// TODO: Implement actual template upload
Ok(())
}
}
// Standalone functions for backward compatibility
pub use super::instance::{check_single_instance, release_instance_lock};
pub use super::vault::{has_installed_stack, reset_vault_only, get_db_password_from_vault};