From b4534c6ee091ed337cfd609b6630aa12e185343c Mon Sep 17 00:00:00 2001 From: Jean-Gabriel Gill-Couture Date: Fri, 4 Jul 2025 10:27:16 -0400 Subject: [PATCH] refact: Make RustWebappScore generic, it is now Application score and takes an application and list of features to attach to the application --- examples/rust/src/main.rs | 22 ++++++++++--------- harmony/Cargo.toml | 2 +- .../features/continuous_delivery.rs | 5 +++++ harmony/src/modules/application/mod.rs | 6 ++--- harmony/src/modules/application/rust.rs | 22 +++++++++++++------ 5 files changed, 36 insertions(+), 21 deletions(-) diff --git a/examples/rust/src/main.rs b/examples/rust/src/main.rs index 235e30c..813485d 100644 --- a/examples/rust/src/main.rs +++ b/examples/rust/src/main.rs @@ -4,7 +4,7 @@ use harmony::{ inventory::Inventory, maestro::Maestro, modules::application::{ - RustWebFramework, RustWebapp, RustWebappScore, features::ContinuousDelivery, + ApplicationScore, RustWebFramework, RustWebapp, features::ContinuousDelivery, }, topology::{K8sAnywhereTopology, Url}, }; @@ -12,18 +12,20 @@ use harmony::{ #[tokio::main] async fn main() { env_logger::init(); - let application = RustWebapp { + let application = Arc::new(RustWebapp { name: "harmony-example-rust-webapp".to_string(), + domain: Url::Url(url::Url::parse("https://rustapp.harmony.example.com").unwrap()), project_root: PathBuf::from("./examples/rust/webapp"), framework: Some(RustWebFramework::Leptos), - }; - // TODO RustWebappScore should simply take a RustWebApp as config - let app = RustWebappScore { - name: "Example Rust Webapp".to_string(), - domain: Url::Url(url::Url::parse("https://rustapp.harmony.example.com").unwrap()), - features: vec![Box::new(ContinuousDelivery { - application: Arc::new(application.clone()), - })], + }); + + let app = ApplicationScore { + features: vec![ + Box::new(ContinuousDelivery { + application: application.clone(), + }), + // TODO add monitoring, backups, multisite ha, etc + ], application, }; diff --git a/harmony/Cargo.toml b/harmony/Cargo.toml index 729fe7e..2a7a97f 100644 --- a/harmony/Cargo.toml +++ b/harmony/Cargo.toml @@ -13,7 +13,7 @@ reqwest = { version = "0.11", features = ["blocking", "json"] } russh = "0.45.0" rust-ipmi = "0.1.1" semver = "1.0.23" -serde = { version = "1.0.209", features = ["derive"] } +serde = { version = "1.0.209", features = ["derive", "rc"] } serde_json = "1.0.127" tokio.workspace = true derive-new.workspace = true diff --git a/harmony/src/modules/application/features/continuous_delivery.rs b/harmony/src/modules/application/features/continuous_delivery.rs index 2dade67..85fd87a 100644 --- a/harmony/src/modules/application/features/continuous_delivery.rs +++ b/harmony/src/modules/application/features/continuous_delivery.rs @@ -153,6 +153,11 @@ impl< "TODO reverse helm chart packaging and docker image build. I put helm package first for faster iterations" ); + // TODO Write CI/CD workflow files + // we can autotedect the CI type using the remote url (default to github action for github + // url, etc..) + // Or ask for it when unknown + let helm_chart = self.application.build_push_helm_package(&image).await?; info!("Pushed new helm chart {helm_chart}"); diff --git a/harmony/src/modules/application/mod.rs b/harmony/src/modules/application/mod.rs index c43e901..afdb88c 100644 --- a/harmony/src/modules/application/mod.rs +++ b/harmony/src/modules/application/mod.rs @@ -23,13 +23,13 @@ pub trait Application: std::fmt::Debug + Send + Sync { } #[derive(Debug)] -pub struct ApplicationInterpret { +pub struct ApplicationInterpret { features: Vec>>, - application: Arc>, + application: Arc, } #[async_trait] -impl Interpret for ApplicationInterpret { +impl Interpret for ApplicationInterpret { async fn execute( &self, _inventory: &Inventory, diff --git a/harmony/src/modules/application/rust.rs b/harmony/src/modules/application/rust.rs index 4a60ac6..401c01f 100644 --- a/harmony/src/modules/application/rust.rs +++ b/harmony/src/modules/application/rust.rs @@ -19,23 +19,30 @@ use crate::{ use super::{Application, ApplicationFeature, ApplicationInterpret, HelmPackage, OCICompliant}; #[derive(Debug, Serialize, Clone)] -pub struct RustWebappScore { - pub name: String, - pub domain: Url, +pub struct ApplicationScore +where + Arc: Serialize + Clone, +{ pub features: Vec>>, - pub application: RustWebapp, + pub application: Arc, } -impl Score for RustWebappScore { +impl< + A: Application + Serialize + Clone + 'static, + T: Topology + std::fmt::Debug + Clone + Serialize + 'static, +> Score for ApplicationScore +where + Arc: Serialize, +{ fn create_interpret(&self) -> Box> { Box::new(ApplicationInterpret { features: self.features.clone(), - application: Arc::new(Box::new(self.application.clone())), + application: self.application.clone(), }) } fn name(&self) -> String { - format!("{}-RustWebapp", self.name) + format!("Application: {}", self.application.name()) } } @@ -47,6 +54,7 @@ pub enum RustWebFramework { #[derive(Debug, Clone, Serialize)] pub struct RustWebapp { pub name: String, + pub domain: Url, /// The path to the root of the Rust project to be containerized. pub project_root: PathBuf, pub framework: Option,