Enhance Docker integration and API for container management
- Implemented Docker container scanning and periodic updates in the Server initialization. - Added new RPC endpoints for managing Docker containers, including start, stop, and restart functionalities. - Updated the API to handle package management for Docker-based applications. - Improved environment variable handling for user-specific configurations in Podman and Docker clients. - Enhanced the development startup script to include Docker container management and provide clearer instructions for full stack setup.
This commit is contained in:
@@ -1,27 +1,54 @@
|
||||
use crate::api::ApiHandler;
|
||||
use crate::config::Config;
|
||||
use crate::config::{Config, ContainerRuntime};
|
||||
use crate::container::DockerPackageScanner;
|
||||
use crate::state::StateManager;
|
||||
use anyhow::Result;
|
||||
use hyper::server::conn::Http;
|
||||
use hyper::service::service_fn;
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use tokio::net::TcpListener;
|
||||
use tracing::error;
|
||||
use tracing::{error, info};
|
||||
|
||||
pub struct Server {
|
||||
_config: Config,
|
||||
api_handler: Arc<ApiHandler>,
|
||||
state_manager: Arc<StateManager>,
|
||||
}
|
||||
|
||||
impl Server {
|
||||
pub async fn new(config: Config) -> Result<Self> {
|
||||
let state_manager = Arc::new(StateManager::new());
|
||||
let api_handler = Arc::new(ApiHandler::new(config.clone(), state_manager).await?);
|
||||
let api_handler = Arc::new(ApiHandler::new(config.clone(), state_manager.clone()).await?);
|
||||
|
||||
// Initialize Docker scanner if in dev mode
|
||||
if config.dev_mode {
|
||||
let scanner = create_docker_scanner(&config).await?;
|
||||
let state = state_manager.clone();
|
||||
|
||||
// Initial scan
|
||||
tokio::spawn(async move {
|
||||
info!("🐳 Scanning Docker containers...");
|
||||
if let Err(e) = scan_and_update_packages(&scanner, &state).await {
|
||||
error!("Failed to scan Docker containers: {}", e);
|
||||
}
|
||||
|
||||
// Periodic scan every 5 seconds
|
||||
let mut interval = tokio::time::interval(Duration::from_secs(5));
|
||||
loop {
|
||||
interval.tick().await;
|
||||
if let Err(e) = scan_and_update_packages(&scanner, &state).await {
|
||||
error!("Failed to update Docker containers: {}", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
_config: config,
|
||||
api_handler,
|
||||
state_manager,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -59,3 +86,39 @@ impl Server {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn create_docker_scanner(config: &Config) -> Result<DockerPackageScanner> {
|
||||
let user = std::env::var("USER").unwrap_or_else(|_| "archipelago".to_string());
|
||||
|
||||
let runtime: Arc<dyn archipelago_container::ContainerRuntime> = match &config.container_runtime {
|
||||
ContainerRuntime::Podman => {
|
||||
Arc::new(archipelago_container::PodmanRuntime::new(user.clone()))
|
||||
}
|
||||
ContainerRuntime::Docker => {
|
||||
Arc::new(archipelago_container::DockerRuntime::new(user.clone()))
|
||||
}
|
||||
ContainerRuntime::Auto => {
|
||||
Arc::new(
|
||||
archipelago_container::AutoRuntime::new(user.clone())
|
||||
.await?
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
Ok(DockerPackageScanner::new(runtime))
|
||||
}
|
||||
|
||||
async fn scan_and_update_packages(
|
||||
scanner: &DockerPackageScanner,
|
||||
state: &StateManager,
|
||||
) -> Result<()> {
|
||||
let packages = scanner.scan_containers().await?;
|
||||
|
||||
if !packages.is_empty() {
|
||||
let (mut data, _) = state.get_snapshot().await;
|
||||
data.package_data = packages;
|
||||
state.update_data(data).await;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user