fix: cache works, modified tar building function to ignore adding autogenerated files from harmony, .git, .github, target, and node_modules file paths\
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Run Check Script / check (pull_request) Successful in 54s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Run Check Script / check (pull_request) Successful in 54s
				
			> tar building function orders files and sets mtime to zero so it is consistent across docker image builds
This commit is contained in:
		
							parent
							
								
									aebde3a382
								
							
						
					
					
						commit
						32ffc3ef61
					
				
							
								
								
									
										48
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										48
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @ -1685,6 +1685,16 @@ dependencies = [ | |||||||
|  "url", |  "url", | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "example-try-rust-webapp" | ||||||
|  | version = "0.1.0" | ||||||
|  | dependencies = [ | ||||||
|  |  "harmony", | ||||||
|  |  "harmony_cli", | ||||||
|  |  "tokio", | ||||||
|  |  "url", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
| [[package]] | [[package]] | ||||||
| name = "example-tui" | name = "example-tui" | ||||||
| version = "0.1.0" | version = "0.1.0" | ||||||
| @ -1700,6 +1710,15 @@ dependencies = [ | |||||||
|  "url", |  "url", | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "example_validate_ceph_cluster_health" | ||||||
|  | version = "0.1.0" | ||||||
|  | dependencies = [ | ||||||
|  |  "harmony", | ||||||
|  |  "harmony_cli", | ||||||
|  |  "tokio", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
| [[package]] | [[package]] | ||||||
| name = "eyre" | name = "eyre" | ||||||
| version = "0.6.12" | version = "0.6.12" | ||||||
| @ -2097,6 +2116,7 @@ dependencies = [ | |||||||
|  "tokio-util", |  "tokio-util", | ||||||
|  "url", |  "url", | ||||||
|  "uuid", |  "uuid", | ||||||
|  |  "walkdir", | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
| [[package]] | [[package]] | ||||||
| @ -4671,6 +4691,15 @@ dependencies = [ | |||||||
|  "cipher", |  "cipher", | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "same-file" | ||||||
|  | version = "1.0.6" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" | ||||||
|  | dependencies = [ | ||||||
|  |  "winapi-util", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
| [[package]] | [[package]] | ||||||
| name = "schannel" | name = "schannel" | ||||||
| version = "0.1.27" | version = "0.1.27" | ||||||
| @ -5961,6 +5990,16 @@ dependencies = [ | |||||||
|  "libc", |  "libc", | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "walkdir" | ||||||
|  | version = "2.5.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" | ||||||
|  | dependencies = [ | ||||||
|  |  "same-file", | ||||||
|  |  "winapi-util", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
| [[package]] | [[package]] | ||||||
| name = "want" | name = "want" | ||||||
| version = "0.3.1" | version = "0.3.1" | ||||||
| @ -6115,6 +6154,15 @@ version = "0.4.0" | |||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" | ||||||
| 
 | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "winapi-util" | ||||||
|  | version = "0.1.10" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22" | ||||||
|  | dependencies = [ | ||||||
|  |  "windows-sys 0.60.2", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
| [[package]] | [[package]] | ||||||
| name = "winapi-x86_64-pc-windows-gnu" | name = "winapi-x86_64-pc-windows-gnu" | ||||||
| version = "0.4.0" | version = "0.4.0" | ||||||
|  | |||||||
| @ -68,6 +68,7 @@ tar.workspace = true | |||||||
| base64.workspace = true | base64.workspace = true | ||||||
| once_cell = "1.21.3" | once_cell = "1.21.3" | ||||||
| harmony-secret-derive = { version = "0.1.0", path = "../harmony_secret_derive" } | harmony-secret-derive = { version = "0.1.0", path = "../harmony_secret_derive" } | ||||||
|  | walkdir = "2.5.0" | ||||||
| 
 | 
 | ||||||
| [dev-dependencies] | [dev-dependencies] | ||||||
| pretty_assertions.workspace = true | pretty_assertions.workspace = true | ||||||
|  | |||||||
| @ -1,4 +1,5 @@ | |||||||
| use std::fs; | use std::fs::{self, File}; | ||||||
|  | use std::io::Read; | ||||||
| use std::path::{Path, PathBuf}; | use std::path::{Path, PathBuf}; | ||||||
| use std::process; | use std::process; | ||||||
| use std::sync::Arc; | use std::sync::Arc; | ||||||
| @ -12,7 +13,8 @@ use dockerfile_builder::instruction_builder::CopyBuilder; | |||||||
| use futures_util::StreamExt; | use futures_util::StreamExt; | ||||||
| use log::{debug, info, log_enabled}; | use log::{debug, info, log_enabled}; | ||||||
| use serde::Serialize; | use serde::Serialize; | ||||||
| use tar::Archive; | use tar::{Archive, Builder, Header}; | ||||||
|  | use walkdir::WalkDir; | ||||||
| 
 | 
 | ||||||
| use crate::config::{REGISTRY_PROJECT, REGISTRY_URL}; | use crate::config::{REGISTRY_PROJECT, REGISTRY_URL}; | ||||||
| use crate::{ | use crate::{ | ||||||
| @ -162,7 +164,6 @@ impl RustWebapp { | |||||||
|     ) -> Result<String, Box<dyn std::error::Error>> { |     ) -> Result<String, Box<dyn std::error::Error>> { | ||||||
|         debug!("Generating Dockerfile for '{}'", self.name); |         debug!("Generating Dockerfile for '{}'", self.name); | ||||||
|         let dockerfile = self.get_or_build_dockerfile(); |         let dockerfile = self.get_or_build_dockerfile(); | ||||||
|         let docker = Docker::connect_with_socket_defaults().unwrap(); |  | ||||||
|         let quiet = !log_enabled!(log::Level::Debug); |         let quiet = !log_enabled!(log::Level::Debug); | ||||||
|         match dockerfile |         match dockerfile | ||||||
|             .unwrap() |             .unwrap() | ||||||
| @ -171,6 +172,14 @@ impl RustWebapp { | |||||||
|         { |         { | ||||||
|             Some(path_str) => { |             Some(path_str) => { | ||||||
|                 debug!("Building from dockerfile {}", path_str); |                 debug!("Building from dockerfile {}", path_str); | ||||||
|  | 
 | ||||||
|  |                 let tar_data = self | ||||||
|  |                     .create_deterministic_tar(&self.project_root.clone()) | ||||||
|  |                     .await | ||||||
|  |                     .unwrap(); | ||||||
|  | 
 | ||||||
|  |                 let docker = Docker::connect_with_socket_defaults().unwrap(); | ||||||
|  | 
 | ||||||
|                 let build_image_options = |                 let build_image_options = | ||||||
|                     bollard::query_parameters::BuildImageOptionsBuilder::default() |                     bollard::query_parameters::BuildImageOptionsBuilder::default() | ||||||
|                         .dockerfile(path_str) |                         .dockerfile(path_str) | ||||||
| @ -178,25 +187,11 @@ impl RustWebapp { | |||||||
|                         .q(quiet) |                         .q(quiet) | ||||||
|                         .version(bollard::query_parameters::BuilderVersion::BuilderV1) |                         .version(bollard::query_parameters::BuilderVersion::BuilderV1) | ||||||
|                         .platform("linux/x86_64"); |                         .platform("linux/x86_64"); | ||||||
|                 let mut temp_tar_builder = tar::Builder::new(Vec::new()); |  | ||||||
|                 temp_tar_builder |  | ||||||
|                     .append_dir_all("", self.project_root.clone()) |  | ||||||
|                     .unwrap(); |  | ||||||
|                 let archive = temp_tar_builder |  | ||||||
|                     .into_inner() |  | ||||||
|                     .expect("couldn't finish creating tar"); |  | ||||||
|                 let archived_files = Archive::new(archive.as_slice()) |  | ||||||
|                     .entries() |  | ||||||
|                     .unwrap() |  | ||||||
|                     .map(|entry| entry.unwrap().path().unwrap().into_owned()) |  | ||||||
|                     .collect::<Vec<_>>(); |  | ||||||
| 
 |  | ||||||
|                 debug!("files in docker tar: {:#?}", archived_files); |  | ||||||
| 
 | 
 | ||||||
|                 let mut image_build_stream = docker.build_image( |                 let mut image_build_stream = docker.build_image( | ||||||
|                     build_image_options.build(), |                     build_image_options.build(), | ||||||
|                     None, |                     None, | ||||||
|                     Some(body_full(archive.into())), |                     Some(body_full(tar_data.into())), | ||||||
|                 ); |                 ); | ||||||
| 
 | 
 | ||||||
|                 while let Some(msg) = image_build_stream.next().await { |                 while let Some(msg) = image_build_stream.next().await { | ||||||
| @ -213,6 +208,56 @@ impl RustWebapp { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     ///normalizes timestamp and ignores files that will bust the docker cach
 | ||||||
|  |     async fn create_deterministic_tar( | ||||||
|  |         &self, | ||||||
|  |         project_root: &std::path::Path, | ||||||
|  |     ) -> Result<Vec<u8>, Box<dyn std::error::Error>> { | ||||||
|  |         debug!("building tar file from project root {:#?}", project_root); | ||||||
|  |         let mut tar_data = Vec::new(); | ||||||
|  |         { | ||||||
|  |             let mut builder = Builder::new(&mut tar_data); | ||||||
|  |             let ignore_prefixes = [ | ||||||
|  |                 "target", | ||||||
|  |                 ".git", | ||||||
|  |                 ".github", | ||||||
|  |                 ".harmony_generated", | ||||||
|  |                 "node_modules", | ||||||
|  |             ]; | ||||||
|  |             let mut entries: Vec<_> = WalkDir::new(project_root) | ||||||
|  |                 .into_iter() | ||||||
|  |                 .filter_map(Result::ok) | ||||||
|  |                 .filter(|e| e.file_type().is_file()) | ||||||
|  |                 .filter(|e| { | ||||||
|  |                     let rel_path = e.path().strip_prefix(project_root).unwrap(); | ||||||
|  |                     !ignore_prefixes | ||||||
|  |                         .iter() | ||||||
|  |                         .any(|prefix| rel_path.starts_with(prefix)) | ||||||
|  |                 }) | ||||||
|  |                 .collect(); | ||||||
|  |             entries.sort_by_key(|e| e.path().to_owned()); | ||||||
|  | 
 | ||||||
|  |             for entry in entries { | ||||||
|  |                 let path = entry.path(); | ||||||
|  |                 let rel_path = path.strip_prefix(project_root).unwrap(); | ||||||
|  | 
 | ||||||
|  |                 let mut file = fs::File::open(path)?; | ||||||
|  |                 let mut header = Header::new_gnu(); | ||||||
|  | 
 | ||||||
|  |                 header.set_size(entry.metadata()?.len()); | ||||||
|  |                 header.set_mode(0o644); | ||||||
|  |                 header.set_mtime(0); | ||||||
|  |                 header.set_uid(0); | ||||||
|  |                 header.set_gid(0); | ||||||
|  | 
 | ||||||
|  |                 builder.append_data(&mut header, rel_path, &mut file)?; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             builder.finish()?; | ||||||
|  |         } | ||||||
|  |         Ok(tar_data) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /// 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, | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user