diff --git a/bin/nanocld/src/main.rs b/bin/nanocld/src/main.rs index 43c6c6698..d064d8929 100644 --- a/bin/nanocld/src/main.rs +++ b/bin/nanocld/src/main.rs @@ -67,6 +67,6 @@ async fn main() -> std::io::Result<()> { } } } - log::info!("shutdown"); + log::info!("main: shutdown"); Ok(()) } diff --git a/bin/nanocld/src/models/namespace.rs b/bin/nanocld/src/models/namespace.rs index 9f7067c22..83c35512a 100644 --- a/bin/nanocld/src/models/namespace.rs +++ b/bin/nanocld/src/models/namespace.rs @@ -1,16 +1,9 @@ -use std::sync::Arc; - use diesel::prelude::*; -use ntex::rt::JoinHandle; use serde::{Serialize, Deserialize}; -use nanocl_error::io::{IoError, IoResult}; - -use nanocl_stubs::{generic::GenericFilter, namespace::NamespacePartial}; - -use crate::{utils, schema::namespaces}; +use nanocl_stubs::namespace::NamespacePartial; -use super::{Pool, Repository}; +use crate::schema::namespaces; /// This structure represent the namespace in the database. /// A namespace is a group of cargo or virtual machine that share the same network. @@ -46,52 +39,3 @@ impl From<&NamespacePartial> for NamespaceDb { } } } - -impl Repository for NamespaceDb { - type Table = namespaces::table; - type Item = NamespaceDb; - type UpdateItem = NamespaceDb; - - fn find_one( - filter: &GenericFilter, - pool: &Pool, - ) -> JoinHandle> { - log::trace!("NamespaceDb::find_one: {filter:?}"); - // let r#where = filter.r#where.to_owned().unwrap_or_default(); - let query = namespaces::dsl::namespaces - .order(namespaces::dsl::created_at.desc()) - .into_boxed(); - let pool = Arc::clone(pool); - ntex::rt::spawn_blocking(move || { - let mut conn = utils::store::get_pool_conn(&pool)?; - let item = query - .get_result::(&mut conn) - .map_err(Self::map_err_context)?; - Ok::<_, IoError>(item) - }) - } - - fn find( - filter: &GenericFilter, - pool: &Pool, - ) -> JoinHandle>> { - log::trace!("NamespaceDb::find: {filter:?}"); - // let r#where = filter.r#where.to_owned().unwrap_or_default(); - let mut query = namespaces::dsl::namespaces - .order(namespaces::dsl::created_at.desc()) - .into_boxed(); - let limit = filter.limit.unwrap_or(100); - query = query.limit(limit as i64); - if let Some(offset) = filter.offset { - query = query.offset(offset as i64); - } - let pool = Arc::clone(pool); - ntex::rt::spawn_blocking(move || { - let mut conn = utils::store::get_pool_conn(&pool)?; - let items = query - .get_results::(&mut conn) - .map_err(Self::map_err_context)?; - Ok::<_, IoError>(items) - }) - } -} diff --git a/bin/nanocld/src/repositories/cargo.rs b/bin/nanocld/src/repositories/cargo.rs index cd3f85d2c..4550832ae 100644 --- a/bin/nanocld/src/repositories/cargo.rs +++ b/bin/nanocld/src/repositories/cargo.rs @@ -29,28 +29,7 @@ impl RepositoryUpdate for CargoDb { type UpdateItem = CargoUpdateDb; } -impl RepositoryDelete for CargoDb { - fn get_del_query( - filter: &GenericFilter, - ) -> diesel::query_builder::BoxedDeleteStatement< - 'static, - diesel::pg::Pg, - ::Table, - > - where - Self: diesel::associations::HasTable, - { - let r#where = filter.r#where.to_owned().unwrap_or_default(); - let mut query = diesel::delete(cargoes::dsl::cargoes).into_boxed(); - if let Some(value) = r#where.get("key") { - gen_where4string!(query, cargoes::dsl::key, value); - } - if let Some(value) = r#where.get("name") { - gen_where4string!(query, cargoes::dsl::name, value); - } - query - } -} +impl RepositoryDelByPk for CargoDb {} impl RepositoryReadWithSpec for CargoDb { type Output = Cargo; diff --git a/bin/nanocld/src/repositories/generic/delete.rs b/bin/nanocld/src/repositories/generic/delete.rs index 300307f3b..21513eddc 100644 --- a/bin/nanocld/src/repositories/generic/delete.rs +++ b/bin/nanocld/src/repositories/generic/delete.rs @@ -1,7 +1,7 @@ use std::sync::Arc; -use diesel::{prelude::*, associations::HasTable, query_dsl, query_builder}; use ntex::rt::JoinHandle; +use diesel::{prelude::*, associations::HasTable, query_dsl, query_builder}; use nanocl_error::io::IoResult; @@ -9,32 +9,22 @@ use nanocl_stubs::generic::GenericFilter; use crate::{utils, models::Pool}; -pub trait RepositoryDelete: super::RepositoryBase { - fn get_del_query( - filter: &GenericFilter, - ) -> diesel::query_builder::BoxedDeleteStatement< - 'static, - diesel::pg::Pg, - ::Table, - > +pub trait RepositoryDelByPk: super::RepositoryBase { + fn del_by_pk( + pk: &Pk, + pool: &Pool, + ) -> JoinHandle> where - Self: diesel::associations::HasTable; - - fn del_by_pk( - pk: &Pk, - pool: &Pool, - ) -> JoinHandle> - where - Self: Sized + HasTable, - Pk: ToOwned + ?Sized + std::fmt::Display, - ::Owned: Send + 'static, - Self::Table: query_dsl::methods::FindDsl<::Owned> + HasTable, - diesel::helper_types::Find::Owned>: query_builder::IntoUpdateTarget, - query_builder::DeleteStatement< - ::Owned> as HasTable>::Table, - ::Owned> as query_builder::IntoUpdateTarget>::WhereClause, - >: query_builder::QueryFragment + query_builder::QueryId, - { + Self: Sized + HasTable, + Pk: ToOwned + ?Sized + std::fmt::Display, + ::Owned: Send + 'static, + Self::Table: query_dsl::methods::FindDsl<::Owned> + HasTable
, + diesel::helper_types::Find::Owned>: query_builder::IntoUpdateTarget, + query_builder::DeleteStatement< + ::Owned> as HasTable>::Table, + ::Owned> as query_builder::IntoUpdateTarget>::WhereClause, + >: query_builder::QueryFragment + query_builder::QueryId, + { log::trace!("{}::delete_by_pk: {pk}", Self::get_name()); let pool = Arc::clone(pool); let pk = pk.to_owned(); @@ -46,6 +36,18 @@ pub trait RepositoryDelete: super::RepositoryBase { Ok(()) }) } +} + +pub trait RepositoryDelBy: super::RepositoryBase { + fn gen_del_query( + filter: &GenericFilter, + ) -> diesel::query_builder::BoxedDeleteStatement< + 'static, + diesel::pg::Pg, + ::Table, + > + where + Self: diesel::associations::HasTable; fn del_by( filter: &GenericFilter, @@ -56,10 +58,11 @@ pub trait RepositoryDelete: super::RepositoryBase { ::Table: diesel::query_builder::QueryId + 'static, <::Table as diesel::QuerySource>::FromClause: diesel::query_builder::QueryFragment, { + log::trace!("{}::delete_by: {filter:?}", Self::get_name()); let pool = Arc::clone(pool); let filter = filter.clone(); ntex::rt::spawn_blocking(move || { - let query = Self::get_del_query(&filter); + let query = Self::gen_del_query(&filter); let mut conn = utils::store::get_pool_conn(&pool)?; query.execute(&mut conn).map_err(Self::map_err)?; Ok(()) diff --git a/bin/nanocld/src/repositories/generic/update.rs b/bin/nanocld/src/repositories/generic/update.rs index 82fcc9571..70fc6f6fa 100644 --- a/bin/nanocld/src/repositories/generic/update.rs +++ b/bin/nanocld/src/repositories/generic/update.rs @@ -17,7 +17,7 @@ pub trait RepositoryUpdate: super::RepositoryBase { ) -> JoinHandle> where T: Into, - Pk: ToOwned + ?Sized, + Pk: ToOwned + ?Sized + std::fmt::Display, ::Owned: Send + 'static, Self: Sized + Send + associations::HasTable + 'static, ::Table: diesel::query_dsl::methods::FindDsl<::Owned> + associations::HasTable
, @@ -33,7 +33,7 @@ pub trait RepositoryUpdate: super::RepositoryBase { >: diesel::query_builder::AsQuery + diesel::query_dsl::LoadQuery<'static, diesel::pg::PgConnection, Self>, { - log::trace!("{}::update_by_pk", Self::get_name()); + log::trace!("{}::update_by_pk: {pk}", Self::get_name()); let pool = Arc::clone(pool); let pk = pk.to_owned(); let values = values.into(); diff --git a/bin/nanocld/src/repositories/mod.rs b/bin/nanocld/src/repositories/mod.rs index 5f2f5a53e..77cb69454 100644 --- a/bin/nanocld/src/repositories/mod.rs +++ b/bin/nanocld/src/repositories/mod.rs @@ -1,4 +1,5 @@ mod cargo; mod process; +mod namespace; pub mod generic; diff --git a/bin/nanocld/src/repositories/namespace.rs b/bin/nanocld/src/repositories/namespace.rs new file mode 100644 index 000000000..1d41ce06d --- /dev/null +++ b/bin/nanocld/src/repositories/namespace.rs @@ -0,0 +1,30 @@ +use diesel::prelude::*; +use nanocl_stubs::generic::GenericFilter; + +use crate::{models::NamespaceDb, schema::namespaces}; + +use super::generic::*; + +impl RepositoryBase for NamespaceDb {} + +impl RepositoryCreate for NamespaceDb {} + +impl RepositoryDelByPk for NamespaceDb {} + +impl RepositoryRead for NamespaceDb { + type Output = NamespaceDb; + type Query = namespaces::BoxedQuery<'static, diesel::pg::Pg>; + + fn gen_read_query(filter: &GenericFilter, is_multiple: bool) -> Self::Query { + let mut query = namespaces::dsl::namespaces.into_boxed(); + if is_multiple { + query = query.order(namespaces::dsl::created_at.desc()); + let limit = filter.limit.unwrap_or(100); + query = query.limit(limit as i64); + if let Some(offset) = filter.offset { + query = query.offset(offset as i64); + } + } + query + } +} diff --git a/bin/nanocld/src/repositories/process.rs b/bin/nanocld/src/repositories/process.rs index e05a5763c..986e5ee84 100644 --- a/bin/nanocld/src/repositories/process.rs +++ b/bin/nanocld/src/repositories/process.rs @@ -19,9 +19,15 @@ impl RepositoryBase for ProcessDb {} impl RepositoryCreate for ProcessDb {} +impl RepositoryUpdate for ProcessDb { + type UpdateItem = ProcessUpdateDb; +} + +impl RepositoryDelByPk for ProcessDb {} + /// Implement delete_by_pk and delete_by_id for ProcessDb -impl RepositoryDelete for ProcessDb { - fn get_del_query( +impl RepositoryDelBy for ProcessDb { + fn gen_del_query( filter: &GenericFilter, ) -> diesel::query_builder::BoxedDeleteStatement< 'static, @@ -86,10 +92,6 @@ impl RepositoryRead for ProcessDb { } } -impl RepositoryUpdate for ProcessDb { - type UpdateItem = ProcessUpdateDb; -} - impl ProcessDb { pub(crate) async fn find_by_kind_key( kind_key: &str, diff --git a/bin/nanocld/src/services/namespace.rs b/bin/nanocld/src/services/namespace.rs index 8be71344e..2f396a327 100644 --- a/bin/nanocld/src/services/namespace.rs +++ b/bin/nanocld/src/services/namespace.rs @@ -2,11 +2,16 @@ use ntex::web; use nanocl_error::http::{HttpResult, HttpError}; -use nanocl_stubs::generic::{GenericFilter, GenericListQuery}; -use nanocl_stubs::namespace::NamespacePartial; +use nanocl_stubs::{ + generic::{GenericFilter, GenericListQuery}, + namespace::NamespacePartial, +}; -use crate::utils; -use crate::models::{DaemonState, Repository, NamespaceDb}; +use crate::{ + utils, + models::{DaemonState, NamespaceDb}, + repositories::generic::RepositoryRead, +}; /// List namespaces #[cfg_attr(feature = "dev", utoipa::path( @@ -92,7 +97,7 @@ pub(crate) async fn delete_namespace( state: web::types::State, path: web::types::Path<(String, String)>, ) -> HttpResult { - NamespaceDb::find_by_pk(&path.1, &state.pool).await??; + NamespaceDb::read_by_pk(&path.1, &state.pool).await??; utils::namespace::delete_by_name(&path.1, &state).await?; Ok(web::HttpResponse::Accepted().into()) } diff --git a/bin/nanocld/src/utils/cargo.rs b/bin/nanocld/src/utils/cargo.rs index 99c69d274..3f2ae4c6c 100644 --- a/bin/nanocld/src/utils/cargo.rs +++ b/bin/nanocld/src/utils/cargo.rs @@ -474,7 +474,7 @@ pub(crate) async fn list( })? .r#where("namespace_name", GenericClause::Eq(namespace.clone())); // ensure namespace exists - NamespaceDb::find_by_pk(&namespace, &state.pool).await??; + NamespaceDb::read_by_pk(&namespace, &state.pool).await??; let cargoes = CargoDb::read_with_spec(&filter, &state.pool).await??; let mut cargo_summaries = Vec::new(); for cargo in cargoes { @@ -528,7 +528,7 @@ pub(crate) async fn delete_by_namespace( namespace: &str, state: &DaemonState, ) -> HttpResult<()> { - let namespace = NamespaceDb::find_by_pk(namespace, &state.pool).await??; + let namespace = NamespaceDb::read_by_pk(namespace, &state.pool).await??; let cargoes = CargoDb::find_by_namespace(&namespace.name, &state.pool).await?; cargoes diff --git a/bin/nanocld/src/utils/namespace.rs b/bin/nanocld/src/utils/namespace.rs index 5dcc84385..b3cf40cff 100644 --- a/bin/nanocld/src/utils/namespace.rs +++ b/bin/nanocld/src/utils/namespace.rs @@ -16,7 +16,8 @@ use nanocl_stubs::{ use crate::{ utils, - models::{Pool, DaemonState, CargoDb, NamespaceDb, Repository}, + repositories::generic::*, + models::{Pool, DaemonState, CargoDb, NamespaceDb}, }; /// Create a new namespace with his associated network. @@ -25,7 +26,7 @@ pub(crate) async fn create( item: &NamespacePartial, state: &DaemonState, ) -> HttpResult { - if NamespaceDb::find_by_pk(&item.name, &state.pool) + if NamespaceDb::read_by_pk(&item.name, &state.pool) .await? .is_ok() { @@ -40,7 +41,7 @@ pub(crate) async fn create( .await .is_ok() { - let res = NamespaceDb::create(item, &state.pool).await??; + let res = NamespaceDb::create_from(item, &state.pool).await??; return Ok(Namespace { name: res.name }); } let config = CreateNetworkOptions { @@ -49,7 +50,7 @@ pub(crate) async fn create( ..Default::default() }; state.docker_api.create_network(config).await?; - let res = NamespaceDb::create(item, &state.pool).await??; + let res = NamespaceDb::create_from(item, &state.pool).await??; Ok(Namespace { name: res.name }) } @@ -59,7 +60,7 @@ pub(crate) async fn delete_by_name( state: &DaemonState, ) -> HttpResult<()> { utils::cargo::delete_by_namespace(name, state).await?; - NamespaceDb::delete_by_pk(name, &state.pool).await??; + NamespaceDb::del_by_pk(name, &state.pool).await??; if let Err(err) = state.docker_api.remove_network(name).await { log::error!("Unable to remove network {} got error: {}", name, err); } @@ -85,11 +86,11 @@ pub(crate) async fn list_instances( /// List all existing namespaces pub(crate) async fn list( - query: &GenericFilter, + filter: &GenericFilter, docker_api: &bollard_next::Docker, pool: &Pool, ) -> HttpResult> { - let items = NamespaceDb::find(query, pool).await??; + let items = NamespaceDb::read(filter, pool).await??; let mut new_items = Vec::new(); for item in items { let cargo_count = CargoDb::count_by_namespace(&item.name, pool).await?; @@ -123,10 +124,8 @@ pub(crate) async fn inspect_by_name( name: &str, state: &DaemonState, ) -> HttpResult { - let namespace = NamespaceDb::find_by_pk(name, &state.pool).await??; - log::debug!("Found namespace to inspect {:?}", &namespace); + let namespace = NamespaceDb::read_by_pk(name, &state.pool).await??; let models = CargoDb::find_by_namespace(&namespace.name, &state.pool).await?; - log::debug!("Found namespace cargoes to inspect {:?}", &models); let mut cargoes = Vec::new(); for cargo in models { let cargo = @@ -149,7 +148,7 @@ pub(crate) async fn create_if_not_exists( name: &str, state: &DaemonState, ) -> HttpResult<()> { - if NamespaceDb::find_by_pk(name, &state.pool).await?.is_err() { + if NamespaceDb::read_by_pk(name, &state.pool).await?.is_err() { create( &NamespacePartial { name: name.to_owned(), diff --git a/bin/nanocld/src/utils/system.rs b/bin/nanocld/src/utils/system.rs index 5f0d3c092..6bac0dcc0 100644 --- a/bin/nanocld/src/utils/system.rs +++ b/bin/nanocld/src/utils/system.rs @@ -90,7 +90,7 @@ pub(crate) async fn register_namespace( create_network: bool, state: &DaemonState, ) -> IoResult<()> { - if NamespaceDb::find_by_pk(name, &state.pool).await?.is_ok() { + if NamespaceDb::read_by_pk(name, &state.pool).await?.is_ok() { return Ok(()); } let new_nsp = NamespacePartial { @@ -99,7 +99,7 @@ pub(crate) async fn register_namespace( if create_network { utils::namespace::create(&new_nsp, state).await?; } else { - NamespaceDb::create(&new_nsp, &state.pool).await??; + NamespaceDb::create_from(&new_nsp, &state.pool).await??; } Ok(()) } diff --git a/bin/nanocld/src/utils/vm.rs b/bin/nanocld/src/utils/vm.rs index efd5285bd..f86366cc3 100644 --- a/bin/nanocld/src/utils/vm.rs +++ b/bin/nanocld/src/utils/vm.rs @@ -18,6 +18,7 @@ use nanocl_stubs::{ use crate::{ utils, + repositories::generic::*, models::{ Pool, VmImageDb, DaemonState, ProcessDb, NamespaceDb, Repository, VmDb, VmSpecDb, FromSpec, @@ -74,7 +75,7 @@ pub(crate) async fn list_by_namespace( nsp: &str, pool: &Pool, ) -> HttpResult> { - let namespace = NamespaceDb::find_by_pk(nsp, pool).await??; + let namespace = NamespaceDb::read_by_pk(nsp, pool).await??; let vmes = VmDb::find_by_namespace(&namespace.name, pool).await?; let mut vm_summaries = Vec::new(); for vm in vmes {