Monitor an application within a tenant #86
							
								
								
									
										30
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,5 +1,25 @@ | |||||||
| target | ### General ### | ||||||
| private_repos | private_repos/ | ||||||
| log/ | 
 | ||||||
| *.tgz | ### Harmony ### | ||||||
| .gitignore | harmony.log | ||||||
|  | 
 | ||||||
|  | ### Helm ### | ||||||
|  | # Chart dependencies | ||||||
|  | **/charts/*.tgz | ||||||
|  | 
 | ||||||
|  | ### Rust ### | ||||||
|  | # Generated by Cargo | ||||||
|  | # will have compiled files and executables | ||||||
|  | debug/ | ||||||
|  | target/ | ||||||
|  | 
 | ||||||
|  | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries | ||||||
|  | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html | ||||||
|  | Cargo.lock | ||||||
|  | 
 | ||||||
|  | # These are backup files generated by rustfmt | ||||||
|  | **/*.rs.bk | ||||||
|  | 
 | ||||||
|  | # MSVC Windows builds of rustc generate these, which store debugging information | ||||||
|  | *.pdb | ||||||
|  | |||||||
							
								
								
									
										3
									
								
								examples/rust/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								examples/rust/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | Dockerfile.harmony | ||||||
|  | .harmony_generated | ||||||
|  | harmony | ||||||
| @ -27,7 +27,7 @@ async fn main() { | |||||||
|     let application = Arc::new(RustWebapp { |     let application = Arc::new(RustWebapp { | ||||||
|         name: "harmony-example-rust-webapp".to_string(), |         name: "harmony-example-rust-webapp".to_string(), | ||||||
|         domain: Url::Url(url::Url::parse("https://rustapp.harmony.example.com").unwrap()), |         domain: Url::Url(url::Url::parse("https://rustapp.harmony.example.com").unwrap()), | ||||||
|         project_root: PathBuf::from("./examples/rust/webapp"), |         project_root: PathBuf::from("./webapp"), // Relative from 'harmony-path' param
 | ||||||
|         framework: Some(RustWebFramework::Leptos), |         framework: Some(RustWebFramework::Leptos), | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
| @ -45,7 +45,7 @@ async fn main() { | |||||||
|         features: vec![ |         features: vec![ | ||||||
|             Box::new(ContinuousDelivery { |             Box::new(ContinuousDelivery { | ||||||
|                 application: application.clone(), |                 application: application.clone(), | ||||||
|             }), // TODO add monitoring, backups, multisite ha, etc
 |             }), | ||||||
|             Box::new(Monitoring { |             Box::new(Monitoring { | ||||||
|                 application: application.clone(), |                 application: application.clone(), | ||||||
|                 alert_receiver: vec![Box::new(discord_receiver), Box::new(webhook_receiver)], |                 alert_receiver: vec![Box::new(discord_receiver), Box::new(webhook_receiver)], | ||||||
|  | |||||||
| @ -1,16 +0,0 @@ | |||||||
| FROM rust:bookworm as builder |  | ||||||
| RUN apt-get update && apt-get install -y --no-install-recommends clang wget && wget https://github.com/cargo-bins/cargo-binstall/releases/latest/download/cargo-binstall-x86_64-unknown-linux-musl.tgz && tar -xvf cargo-binstall-x86_64-unknown-linux-musl.tgz && cp cargo-binstall /usr/local/cargo/bin && rm cargo-binstall-x86_64-unknown-linux-musl.tgz cargo-binstall && apt-get clean && rm -rf /var/lib/apt/lists/* |  | ||||||
| RUN cargo binstall cargo-leptos -y |  | ||||||
| RUN rustup target add wasm32-unknown-unknown |  | ||||||
| WORKDIR /app |  | ||||||
| COPY . . |  | ||||||
| RUN cargo leptos build --release -vv |  | ||||||
| FROM debian:bookworm-slim |  | ||||||
| RUN groupadd -r appgroup && useradd -r -s /bin/false -g appgroup appuser |  | ||||||
| ENV LEPTOS_SITE_ADDR=0.0.0.0:3000 |  | ||||||
| EXPOSE 3000/tcp |  | ||||||
| WORKDIR /home/appuser |  | ||||||
| COPY --from=builder /app/target/site/pkg /home/appuser/pkg |  | ||||||
| COPY --from=builder /app/target/release/harmony-example-rust-webapp /home/appuser/harmony-example-rust-webapp |  | ||||||
| USER appuser |  | ||||||
| CMD /home/appuser/harmony-example-rust-webapp |  | ||||||
| @ -158,7 +158,7 @@ impl< | |||||||
|         let helm_chart = self.application.build_push_helm_package(&image).await?; |         let helm_chart = self.application.build_push_helm_package(&image).await?; | ||||||
|         info!("Pushed new helm chart {helm_chart}"); |         info!("Pushed new helm chart {helm_chart}"); | ||||||
| 
 | 
 | ||||||
|         error!("TODO Make building image configurable/skippable"); |         error!("TODO Make building image configurable/skippable if image already exists (prompt)"); | ||||||
|         let image = self.application.build_push_oci_image().await?; |         let image = self.application.build_push_oci_image().await?; | ||||||
|         info!("Pushed new docker image {image}"); |         info!("Pushed new docker image {image}"); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -109,24 +109,20 @@ impl OCICompliant for RustWebapp { | |||||||
|         // It's async to match the trait definition, though the underlying docker commands are blocking.
 |         // It's async to match the trait definition, though the underlying docker commands are blocking.
 | ||||||
|         info!("Starting OCI image build and push for '{}'", self.name); |         info!("Starting OCI image build and push for '{}'", self.name); | ||||||
| 
 | 
 | ||||||
|         // 1. Build the local image by calling the synchronous helper function.
 |         // 1. Build the image by calling the synchronous helper function.
 | ||||||
|         let local_image_name = self.local_image_name(); |         let image_tag = self.image_name(); | ||||||
|         self.build_docker_image(&local_image_name) |         self.build_docker_image(&image_tag) | ||||||
|             .await |             .await | ||||||
|             .map_err(|e| format!("Failed to build Docker image: {}", e))?; |             .map_err(|e| format!("Failed to build Docker image: {}", e))?; | ||||||
|         info!( |         info!("Successfully built Docker image: {}", image_tag); | ||||||
|             "Successfully built local Docker image: {}", |  | ||||||
|             local_image_name |  | ||||||
|         ); |  | ||||||
| 
 | 
 | ||||||
|         let remote_image_name = self.image_name(); |  | ||||||
|         // 2. Push the image to the registry.
 |         // 2. Push the image to the registry.
 | ||||||
|         self.push_docker_image(&local_image_name, &remote_image_name) |         self.push_docker_image(&image_tag) | ||||||
|             .await |             .await | ||||||
|             .map_err(|e| format!("Failed to push Docker image: {}", e))?; |             .map_err(|e| format!("Failed to push Docker image: {}", e))?; | ||||||
|         info!("Successfully pushed Docker image to: {}", remote_image_name); |         info!("Successfully pushed Docker image to: {}", image_tag); | ||||||
| 
 | 
 | ||||||
|         Ok(remote_image_name) |         Ok(image_tag) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn local_image_name(&self) -> String { |     fn local_image_name(&self) -> String { | ||||||
| @ -206,23 +202,25 @@ impl RustWebapp { | |||||||
|     /// Tags and pushes a Docker image to the configured remote registry.
 |     /// Tags and pushes a Docker image to the configured remote registry.
 | ||||||
|     async fn push_docker_image( |     async fn push_docker_image( | ||||||
|         &self, |         &self, | ||||||
|         image_name: &str, |         image_tag: &str, | ||||||
|         full_tag: &str, |  | ||||||
|     ) -> Result<String, Box<dyn std::error::Error>> { |     ) -> Result<String, Box<dyn std::error::Error>> { | ||||||
|         info!("Pushing docker image {full_tag}"); |         info!("Pushing docker image {image_tag}"); | ||||||
| 
 | 
 | ||||||
|         let docker = Docker::connect_with_socket_defaults().unwrap(); |         let docker = Docker::connect_with_socket_defaults().unwrap(); | ||||||
| 
 | 
 | ||||||
|         // let push_options = PushImageOptionsBuilder::new().tag(tag);
 |         // let push_options = PushImageOptionsBuilder::new().tag(tag);
 | ||||||
| 
 | 
 | ||||||
|         let mut push_image_stream = |         let mut push_image_stream = docker.push_image( | ||||||
|             docker.push_image(full_tag, Some(PushImageOptionsBuilder::new().build()), None); |             image_tag, | ||||||
|  |             Some(PushImageOptionsBuilder::new().build()), | ||||||
|  |             None, | ||||||
|  |         ); | ||||||
| 
 | 
 | ||||||
|         while let Some(msg) = push_image_stream.next().await { |         while let Some(msg) = push_image_stream.next().await { | ||||||
|             println!("Message: {msg:?}"); |             println!("Message: {msg:?}"); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         Ok(full_tag.to_string()) |         Ok(image_tag.to_string()) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Checks the output of a process command for success.
 |     /// Checks the output of a process command for success.
 | ||||||
|  | |||||||
| @ -98,7 +98,9 @@ async fn main() { | |||||||
|                     .expect("couldn't check if path exists") |                     .expect("couldn't check if path exists") | ||||||
|                 { |                 { | ||||||
|                     true => (), |                     true => (), | ||||||
|                     false => todo!("implement couldn't find path logic"), |                     false => todo!( | ||||||
|  |                         "path {check_script_str} not found. Other paths currently unsupported." | ||||||
|  |                     ), | ||||||
|                 }; |                 }; | ||||||
| 
 | 
 | ||||||
|                 let check_output = Command::new(check_script) |                 let check_output = Command::new(check_script) | ||||||
| @ -155,6 +157,7 @@ async fn compile_harmony( | |||||||
| 
 | 
 | ||||||
|     let cargo_exists = Command::new("which") |     let cargo_exists = Command::new("which") | ||||||
|         .arg("cargo") |         .arg("cargo") | ||||||
|  |         .stdout(Stdio::null()) | ||||||
|         .status() |         .status() | ||||||
|         .expect("couldn't get `which cargo` status") |         .expect("couldn't get `which cargo` status") | ||||||
|         .success(); |         .success(); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user