From fe5b97425fa08854b4f1ce37451166f8a81d54d2 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 22 Feb 2021 10:44:19 +0100 Subject: Multiple release stores This patch adds the ability to have more than one release store. With this patch, a user can (has to) configure release store names in the configuration file, and can then specify one of the configured names to release the artifacts to. This way, different release "channels" can be served, for example a stable channel and a rolling release channel (although "channel" is not in our wording). The code was adapted to be able to fetch releases from multiple release directories, in the crate::db::find_artifact implementation, so that re-using artifacts works across all release directories. Signed-off-by: Matthias Beyer --- src/endpoint/configured.rs | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'src/endpoint/configured.rs') diff --git a/src/endpoint/configured.rs b/src/endpoint/configured.rs index b90263e..6385f26 100644 --- a/src/endpoint/configured.rs +++ b/src/endpoint/configured.rs @@ -223,9 +223,9 @@ impl Endpoint { &self, job: RunnableJob, staging_store: Arc>, - release_store: Arc>, + release_stores: Vec>, ) -> Result> { - PreparedContainer::new(self, job, staging_store, release_store).await + PreparedContainer::new(self, job, staging_store, release_stores).await } pub async fn number_of_running_containers(&self) -> Result { @@ -253,7 +253,7 @@ impl<'a> PreparedContainer<'a> { endpoint: &'a Endpoint, job: RunnableJob, staging_store: Arc>, - release_store: Arc>, + release_stores: Vec>, ) -> Result> { let script = job.script().clone(); let create_info = Self::build_container(endpoint, &job).await?; @@ -261,7 +261,7 @@ impl<'a> PreparedContainer<'a> { let (cpysrc, cpyart, cpyscr) = tokio::join!( Self::copy_source_to_container(&container, &job), - Self::copy_artifacts_to_container(&container, &job, staging_store, release_store), + Self::copy_artifacts_to_container(&container, &job, staging_store, &release_stores), Self::copy_script_to_container(&container, &script) ); @@ -386,7 +386,7 @@ impl<'a> PreparedContainer<'a> { container: &Container<'ca>, job: &RunnableJob, staging_store: Arc>, - release_store: Arc>, + release_stores: &[Arc], ) -> Result<()> { job.resources() .iter() @@ -410,14 +410,24 @@ impl<'a> PreparedContainer<'a> { destination.display() ); let staging_read = staging_store.read().await; - let release_read = release_store.read().await; let buf = match staging_read.root_path().join(&art)? { Some(fp) => fp, None => { - release_read - .root_path() - .join(&art)? - .ok_or_else(|| anyhow!("Not found in staging or release store: {:?}", art))? + // TODO: Optimize. + // I know this is not nice, but it works for now. + let mut found = None; + for release_store in release_stores.iter() { + let p = release_store.root_path().join(&art); + match p { + Ok(Some(path)) => { + found = Some(path); + break; + }, + Err(e) => return Err(e), + Ok(None) => continue, + } + } + found.ok_or_else(|| anyhow!("Not found in staging or release store: {:?}", art))? }, } .read() -- cgit v1.2.3