From 6e85bda13f0ad6bca04197c86b42e4fd25f688b2 Mon Sep 17 00:00:00 2001 From: GW_MC <72297530+GWMCwing@users.noreply.github.com> Date: Mon, 22 Dec 2025 14:32:57 +0800 Subject: [PATCH] Refactor container definitions --- apps/cli/src/cmd/db_migrate_and_generate.rs | 4 +- apps/container/src/containers.rs | 40 +++++++++++++++++++ apps/container/src/{ => containers}/agent.rs | 7 +--- apps/container/src/{ => containers}/db.rs | 15 +++---- .../src/{ => containers}/db/config.rs | 0 .../src/{ => containers}/db/postgresql.rs | 11 +++-- .../src/{ => containers}/db/sqlite.rs | 4 +- apps/container/src/env.rs | 33 +++++---------- apps/container/src/lib.rs | 10 ++--- apps/container/src/main.rs | 22 +++++----- apps/container/src/types.rs | 25 ------------ apps/container/src/util.rs | 12 ++++-- 12 files changed, 92 insertions(+), 91 deletions(-) create mode 100644 apps/container/src/containers.rs rename apps/container/src/{ => containers}/agent.rs (95%) rename apps/container/src/{ => containers}/db.rs (73%) rename apps/container/src/{ => containers}/db/config.rs (100%) rename apps/container/src/{ => containers}/db/postgresql.rs (91%) rename apps/container/src/{ => containers}/db/sqlite.rs (95%) delete mode 100644 apps/container/src/types.rs diff --git a/apps/cli/src/cmd/db_migrate_and_generate.rs b/apps/cli/src/cmd/db_migrate_and_generate.rs index a563431..79865c9 100644 --- a/apps/cli/src/cmd/db_migrate_and_generate.rs +++ b/apps/cli/src/cmd/db_migrate_and_generate.rs @@ -1,7 +1,7 @@ use clap::{Arg, Command}; -use container::{ +use container::containers::{ + ConfigInfoType, db::{DBInfo, sqlite::SQLiteContainer}, - types::ConfigInfoType, }; use migration::{generate_entity, migrate_database}; use shared::db_type::DBType; diff --git a/apps/container/src/containers.rs b/apps/container/src/containers.rs new file mode 100644 index 0000000..3552467 --- /dev/null +++ b/apps/container/src/containers.rs @@ -0,0 +1,40 @@ +pub mod agent; +pub mod db; + +use std::{pin::Pin, sync::Arc}; + +use testcontainers::{ContainerAsync, GenericImage, TestcontainersError}; + +use crate::containers::{ + agent::AgentContainerInfo, + db::{ContainerizedDBInfo, PreExistingDBInfo}, +}; + +pub type UnStartedContainer = + Pin, TestcontainersError>> + Send>>; + +pub type AgentConfigInfoType = ConfigInfoType; + +pub type DBConfigInfoType = ConfigInfoType; + +pub trait WithContainer { + fn container(&self) -> &Arc>; +} + +pub trait WithoutContainer { + fn on_delete(&self); +} + +impl WithoutContainer for () { + fn on_delete(&self) {} +} + +#[derive(Clone)] +pub enum ConfigInfoType +where + T: WithContainer, + U: WithoutContainer, +{ + Containerized(T), + PreExisting(U), +} diff --git a/apps/container/src/agent.rs b/apps/container/src/containers/agent.rs similarity index 95% rename from apps/container/src/agent.rs rename to apps/container/src/containers/agent.rs index ee08852..ebe2743 100644 --- a/apps/container/src/agent.rs +++ b/apps/container/src/containers/agent.rs @@ -5,10 +5,7 @@ use testcontainers::{ runners::{AsyncBuilder, AsyncRunner}, }; -use crate::{ - db::UnStartedContainer, - types::{ConfigInfoType, WithContainer}, -}; +use crate::{WithContainer, containers::UnStartedContainer}; pub const SOCK_NAME: &str = "yanpm-agent.sock"; const SOCK_FOLDER: &str = "/var/run/yanpm"; @@ -25,8 +22,6 @@ pub struct AgentContainerConfig { pub nginx_config: NginxConfig, } -pub type AgentConfigInfoType = ConfigInfoType; - #[derive(Clone)] pub struct AgentContainerInfo { pub container: Arc>, diff --git a/apps/container/src/db.rs b/apps/container/src/containers/db.rs similarity index 73% rename from apps/container/src/db.rs rename to apps/container/src/containers/db.rs index 11f7505..dcd61f0 100644 --- a/apps/container/src/db.rs +++ b/apps/container/src/containers/db.rs @@ -5,18 +5,15 @@ pub mod sqlite; use async_trait::async_trait; use shared::db_type::DBType; use std::error::Error; -use std::future::Future; -use std::{pin::Pin, sync::Arc}; +use std::sync::Arc; use url::Host; -use testcontainers::{ContainerAsync, GenericImage, TestcontainersError}; +use testcontainers::{ContainerAsync, GenericImage}; -use crate::{ConfigInfoType, WithContainer, WithoutContainer}; - -pub type UnStartedContainer = - Pin, TestcontainersError>> + Send>>; - -pub type DBConfigInfoType = ConfigInfoType; +use crate::{ + WithContainer, WithoutContainer, + containers::{DBConfigInfoType, UnStartedContainer}, +}; #[derive(Clone)] pub struct PreExistingDBInfo { diff --git a/apps/container/src/db/config.rs b/apps/container/src/containers/db/config.rs similarity index 100% rename from apps/container/src/db/config.rs rename to apps/container/src/containers/db/config.rs diff --git a/apps/container/src/db/postgresql.rs b/apps/container/src/containers/db/postgresql.rs similarity index 91% rename from apps/container/src/db/postgresql.rs rename to apps/container/src/containers/db/postgresql.rs index 5c0cec2..813450c 100644 --- a/apps/container/src/db/postgresql.rs +++ b/apps/container/src/containers/db/postgresql.rs @@ -9,9 +9,12 @@ use testcontainers::{ use crate::{ ConfigInfoType, - db::{ - ContainerizedDBInfo, DBConfigInfoType, DBInfo, UnStartedContainer, - config::{DatabaseContainerConfig, OptionalContainerConfig}, + containers::{ + UnStartedContainer, + db::{ + ContainerizedDBInfo, DBConfigInfoType, DBInfo, + config::{DatabaseContainerConfig, OptionalContainerConfig}, + }, }, }; @@ -53,7 +56,7 @@ impl DBInfo for PostgreSQLContainer { ); ConfigInfoType::Containerized(ContainerizedDBInfo { - db_type: crate::db::DBType::PostgreSQL, + db_type: crate::containers::db::DBType::PostgreSQL, container: Arc::new(pg_container), container_name: self.config.container_name.clone(), database_name: self.config.database_name.clone(), diff --git a/apps/container/src/db/sqlite.rs b/apps/container/src/containers/db/sqlite.rs similarity index 95% rename from apps/container/src/db/sqlite.rs rename to apps/container/src/containers/db/sqlite.rs index cf0dd40..ef0f579 100644 --- a/apps/container/src/db/sqlite.rs +++ b/apps/container/src/containers/db/sqlite.rs @@ -4,7 +4,7 @@ use async_trait::async_trait; use crate::{ ConfigInfoType, - db::{DBConfigInfoType, DBInfo, PreExistingDBInfo, UnStartedContainer}, + containers::db::{DBConfigInfoType, DBInfo, PreExistingDBInfo, UnStartedContainer}, util::to_absolute_path, }; @@ -69,7 +69,7 @@ impl DBInfo for SQLiteContainer { .expect("Failed to create SQLite database file"); // ConfigInfoType::PreExisting(PreExistingDBInfo { - db_type: crate::db::DBType::SQLite, + db_type: crate::containers::db::DBType::SQLite, url: sqlite_url, on_delete: { let db_path = self.get_db_absolute_path(); diff --git a/apps/container/src/env.rs b/apps/container/src/env.rs index 0c2200b..58710cd 100644 --- a/apps/container/src/env.rs +++ b/apps/container/src/env.rs @@ -1,7 +1,5 @@ use std::io::Write; -use shared::db_type::DBType; - #[derive(Clone, Copy)] pub enum EnvFileType { DotEnv, @@ -11,25 +9,16 @@ pub enum EnvFileType { #[derive(Clone)] pub struct EnvFile { pub file_type: EnvFileType, - pub db_type: DBType, - pub db_url: String, // buffer: serde_json::Value, } impl EnvFile { - pub fn new(file_type: EnvFileType, db_type: DBType, db_url: String) -> Self { - let mut env_file = EnvFile { + pub fn new(file_type: EnvFileType) -> Self { + EnvFile { file_type, - db_type, - db_url, buffer: serde_json::Value::Object(serde_json::Map::new()), - }; - - env_file._write_line_buffer("DATABASE__TYPE", &env_file.db_type.to_string()); - env_file._write_line_buffer("DATABASE__URL", &env_file.db_url.to_string()); - - env_file + } } pub fn write_line(&mut self, key: &str, value: &str) { @@ -131,12 +120,10 @@ mod tests { #[test] fn test_env_file_write_yaml() { - let mut env_file_nested = EnvFile::new( - EnvFileType::Yaml, - DBType::SQLite, - "mysql://user:pass@localhost/db".to_string(), - ); + let mut env_file_nested = EnvFile::new(EnvFileType::Yaml); + env_file_nested.write_line("DATABASE__TYPE", "SQLite"); + env_file_nested.write_line("DATABASE__URL", "mysql://user:pass@localhost/db"); let mut output_stream = Vec::new(); env_file_nested.write(&mut output_stream, false); let output_string = String::from_utf8(output_stream).unwrap(); @@ -150,11 +137,9 @@ DATABASE: #[test] fn test_env_file_write_env() { - let mut env_file_nested = EnvFile::new( - EnvFileType::DotEnv, - DBType::PostgreSQL, - "postgres://user:pass@localhost/db".to_string(), - ); + let mut env_file_nested = EnvFile::new(EnvFileType::DotEnv); + env_file_nested.write_line("DATABASE__TYPE", "PostgreSQL"); + env_file_nested.write_line("DATABASE__URL", "postgres://user:pass@localhost/db"); let mut output_stream = Vec::new(); env_file_nested.write(&mut output_stream, true); let output_string = String::from_utf8(output_stream).unwrap(); diff --git a/apps/container/src/lib.rs b/apps/container/src/lib.rs index bd2fee4..7f651e8 100644 --- a/apps/container/src/lib.rs +++ b/apps/container/src/lib.rs @@ -1,13 +1,11 @@ -pub mod agent; -pub mod db; +pub mod containers; mod env; -pub mod types; mod util; use crate::{ - agent::AgentConfigInfoType, - db::DBConfigInfoType, - types::{ConfigInfoType, WithContainer, WithoutContainer}, + containers::{ + AgentConfigInfoType, ConfigInfoType, DBConfigInfoType, WithContainer, WithoutContainer, + }, util::{ await_termination_signal, remove_file_if_exists, stop_container, to_absolute_path, write_env_files, diff --git a/apps/container/src/main.rs b/apps/container/src/main.rs index cffd7c2..9cb6b2c 100644 --- a/apps/container/src/main.rs +++ b/apps/container/src/main.rs @@ -1,12 +1,15 @@ use std::sync::Arc; use clap::Parser; -use container::agent::{AgentConfig, AgentContainerConfig, AgentContainerInfo, NginxConfig}; -use container::start_attached; -use container::types::ConfigInfoType; -use container::{Config, agent}; - -use container::db::DBInfo; +use container::{ + Config, + containers::{ + ConfigInfoType, + agent::{AgentConfig, AgentContainerConfig, AgentContainerInfo, NginxConfig}, + db::DBInfo, + }, + start_attached, +}; /// Command line arguments #[derive(Parser, Debug)] @@ -65,7 +68,7 @@ async fn main() { println!("Starting container with database type: {}", args.db_type); let db_config = match args.db_type.to_lowercase().as_str() { "postgres" | "pg" | "pgsql" => { - use container::db::postgresql::PostgreSQLContainer; + use container::containers::db::postgresql::PostgreSQLContainer; println!("Using PostgreSQL database"); PostgreSQLContainer::new(None) .await @@ -74,7 +77,7 @@ async fn main() { } "sqlite" | "sql" => { println!("Using SQLite database"); - use container::db::sqlite::SQLiteContainer; + use container::containers::db::sqlite::SQLiteContainer; SQLiteContainer::new(None) .await .get_db_container_config_info() @@ -89,7 +92,7 @@ async fn main() { let agent_container = if let Some(agent_config) = &args.agent_container_config { println!( - "Agent container will be used with socket path: {} and nginx config dir: {}", + "Agent container will be used with socket folder: {} and nginx config dir: {}", agent_config.agent_config.sock_folder, agent_config.agent_config.nginx_config_dir ); Some(agent_config.get_unstarted_container().await) @@ -168,6 +171,7 @@ async fn parse_args() -> ParsedArgs { ParsedArgs { db_type: args.db_type, agent_container_config: Some(AgentContainerConfig { + // TODO: allow customization of these fields via CLI args image: "yanpm-agent".to_string(), tag: "latest".to_string(), container_name: format!("yanpm-agent-container-{}", time), diff --git a/apps/container/src/types.rs b/apps/container/src/types.rs deleted file mode 100644 index e43e702..0000000 --- a/apps/container/src/types.rs +++ /dev/null @@ -1,25 +0,0 @@ -use std::sync::Arc; - -use testcontainers::{ContainerAsync, GenericImage}; - -pub trait WithContainer { - fn container(&self) -> &Arc>; -} - -pub trait WithoutContainer { - fn on_delete(&self); -} - -impl WithoutContainer for () { - fn on_delete(&self) {} -} - -#[derive(Clone)] -pub enum ConfigInfoType -where - T: WithContainer, - U: WithoutContainer, -{ - Containerized(T), - PreExisting(U), -} diff --git a/apps/container/src/util.rs b/apps/container/src/util.rs index c80fada..200ea51 100644 --- a/apps/container/src/util.rs +++ b/apps/container/src/util.rs @@ -4,10 +4,11 @@ use tokio::signal::unix::{SignalKind, signal}; use crate::{ API_CONFIG_PATH, DB_CONFIG_PATH, - agent::{AgentConfigInfoType, AgentContainerInfo, SOCK_NAME}, - db::DBConfigInfoType, + containers::{ + AgentConfigInfoType, ConfigInfoType, DBConfigInfoType, WithContainer, WithoutContainer, + agent::SOCK_NAME, + }, env::{self, EnvFile}, - types::{ConfigInfoType, WithContainer, WithoutContainer}, }; // relative to the current working directory @@ -30,7 +31,10 @@ pub fn write_env_files(db_config: &DBConfigInfoType, agent_config: &Option (config.db_type.clone(), config.url.clone()), }; - let mut api_env = EnvFile::new(env::EnvFileType::Yaml, db_type, db_url); + let mut api_env = EnvFile::new(env::EnvFileType::Yaml); + api_env.write_line("DATABASE__TYPE", db_type.to_string().as_str()); + api_env.write_line("DATABASE__URL", db_url.as_str()); + let mut db_env = api_env.clone(); db_env.file_type = env::EnvFileType::DotEnv;