From 2d72cbed2495517dba84ec4d46e5f521ff46412b Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 1 Mar 2021 10:16:42 +0100 Subject: Add feature to pass git author and git commit information to container This patch implements the feature to be able to pass author and commit hash information from the repository to the container. This can be used to set packager or package description commit hash inside the build container, if desired. Signed-off-by: Matthias Beyer --- config.toml | 16 ++++++++++++++ src/commands/build.rs | 1 + src/config/container_config.rs | 9 ++++++++ src/job/runnable.rs | 6 ++++++ src/orchestrator/orchestrator.rs | 46 ++++++++++++++++++++++++++++++++++++++-- 5 files changed, 76 insertions(+), 2 deletions(-) diff --git a/config.toml b/config.toml index c47f6c5..5f504ef 100644 --- a/config.toml +++ b/config.toml @@ -203,3 +203,19 @@ check_env_names = true # Double-check this list allowed_env = [ "FOO", "BAR" ] +# Use the git author information and pass it to each container as environment +# variable. +# The information is passed with +# +# Bob Baumeister +# +# in the environment variable named as value here. +# +# If this is not set, this feature is disabled. +#git_author = "GIT_AUTHOR_INFO" + +# Use the git hash of the repository and pass it to each container as +# environment variable. +# If this is not set, this feature is disabled. +#git_commit_hash = "GIT_COMMIT_HASH" + diff --git a/src/commands/build.rs b/src/commands/build.rs index 4474d4e..85697d6 100644 --- a/src/commands/build.rs +++ b/src/commands/build.rs @@ -343,6 +343,7 @@ pub async fn build( }) .jobdag(jobdag) .config(config) + .repository(git_repo) .build() .setup() .await?; diff --git a/src/config/container_config.rs b/src/config/container_config.rs index f117351..36cfe1a 100644 --- a/src/config/container_config.rs +++ b/src/config/container_config.rs @@ -24,4 +24,13 @@ pub struct ContainerConfig { /// Allowed environment variables (names) #[getset(get = "pub")] allowed_env: Vec, + + /// Pass the current git author to the container + /// This can be used to the the "packager" name in a package, for example + #[getset(get = "pub")] + git_author: Option, + + /// Pass the current git hash to the container + #[getset(get = "pub")] + git_commit_hash: Option, } diff --git a/src/job/runnable.rs b/src/job/runnable.rs index 838a4e7..3143e0c 100644 --- a/src/job/runnable.rs +++ b/src/job/runnable.rs @@ -55,6 +55,8 @@ impl RunnableJob { job: &Job, source_cache: &SourceCache, config: &Configuration, + git_author_env: Option<&(EnvironmentVariableName, String)>, + git_commit_env: Option<&(EnvironmentVariableName, String)>, dependencies: Vec, ) -> Result { if config.containers().check_env_names() { @@ -70,6 +72,8 @@ impl RunnableJob { .into_iter() .flatten() }) + .chain(git_author_env.as_ref().into_iter().map(|(k, v)| (k, v))) + .chain(git_commit_env.as_ref().into_iter().map(|(k, v)| (k, v))) .inspect(|(name, _)| debug!("Checking: {}", name)) .try_for_each(|(name, _)| { trace!("{:?} contains? {:?}", config.containers().allowed_env(), name); @@ -100,6 +104,8 @@ impl RunnableJob { .filter(|jr| jr.env().is_some()) .cloned() }) + .chain(git_author_env.into_iter().cloned().map(JobResource::from)) + .chain(git_commit_env.into_iter().cloned().map(JobResource::from)) .collect(); debug!("Building script now"); diff --git a/src/orchestrator/orchestrator.rs b/src/orchestrator/orchestrator.rs index dc32925..cc57a49 100644 --- a/src/orchestrator/orchestrator.rs +++ b/src/orchestrator/orchestrator.rs @@ -19,17 +19,18 @@ use anyhow::Error; use anyhow::Result; use anyhow::anyhow; use diesel::PgConnection; +use git2::Repository; use indicatif::ProgressBar; use itertools::Itertools; use log::debug; use log::trace; +use resiter::FilterMap; use tokio::sync::RwLock; use tokio::sync::mpsc::Receiver; use tokio::sync::mpsc::Sender; use tokio_stream::StreamExt; use typed_builder::TypedBuilder; use uuid::Uuid; -use resiter::FilterMap; use crate::config::Configuration; use crate::db::models as dbmodels; @@ -38,10 +39,11 @@ use crate::endpoint::EndpointScheduler; use crate::filestore::ArtifactPath; use crate::filestore::ReleaseStore; use crate::filestore::StagingStore; +use crate::job::Dag; use crate::job::JobDefinition; use crate::job::RunnableJob; -use crate::job::Dag; use crate::source::SourceCache; +use crate::util::EnvironmentVariableName; use crate::util::progress::ProgressBars; #[cfg_attr(doc, aquamarine::aquamarine)] @@ -159,6 +161,7 @@ pub struct Orchestrator<'a> { source_cache: SourceCache, jobdag: Dag, config: &'a Configuration, + repository: Repository, database: Arc, } @@ -174,6 +177,7 @@ pub struct OrchestratorSetup<'a> { submit: dbmodels::Submit, log_dir: Option, config: &'a Configuration, + repository: Repository, } impl<'a> OrchestratorSetup<'a> { @@ -197,6 +201,7 @@ impl<'a> OrchestratorSetup<'a> { jobdag: self.jobdag, config: self.config, database: self.database, + repository: self.repository, }) } } @@ -226,6 +231,33 @@ impl<'a> Orchestrator<'a> { mp }); + let git_author_env = { + self.config + .containers() + .git_author() + .as_ref() + .map(|varname| -> Result<_> { + let username = self.repository + .config()? + .get_string("user.name")?; + + Ok((varname.clone(), username)) + }) + .transpose()? + }; + + let git_commit_env = { + self.config + .containers() + .git_commit_hash() + .as_ref() + .map(|varname| -> Result<_> { + let hash = crate::util::git::get_repo_head_commit_hash(&self.repository)?; + Ok((varname.clone(), hash)) + }) + .transpose()? + }; + // For each job in the jobdag, built a tuple with // // 1. The receiver that is used by the task to receive results from dependency tasks from @@ -252,6 +284,8 @@ impl<'a> Orchestrator<'a> { bar, config: self.config, + git_author_env: git_author_env.as_ref(), + git_commit_env: git_commit_env.as_ref(), source_cache: &self.source_cache, scheduler: &self.scheduler, staging_store: self.staging_store.clone(), @@ -370,6 +404,8 @@ struct TaskPreparation<'a> { bar: ProgressBar, config: &'a Configuration, + git_author_env: Option<&'a (EnvironmentVariableName, String)>, + git_commit_env: Option<&'a (EnvironmentVariableName, String)>, source_cache: &'a SourceCache, scheduler: &'a EndpointScheduler, staging_store: Arc>, @@ -386,6 +422,8 @@ struct JobTask<'a> { bar: ProgressBar, config: &'a Configuration, + git_author_env: Option<&'a (EnvironmentVariableName, String)>, + git_commit_env: Option<&'a (EnvironmentVariableName, String)>, source_cache: &'a SourceCache, scheduler: &'a EndpointScheduler, staging_store: Arc>, @@ -442,6 +480,8 @@ impl<'a> JobTask<'a> { bar, config: prep.config, + git_author_env: prep.git_author_env, + git_commit_env: prep.git_commit_env, source_cache: prep.source_cache, scheduler: prep.scheduler, staging_store: prep.staging_store, @@ -625,6 +665,8 @@ impl<'a> JobTask<'a> { &self.jobdef.job, self.source_cache, self.config, + self.git_author_env, + self.git_commit_env, dependency_artifacts)?; self.bar.set_message(&format!("[{} {} {}]: Scheduling...", -- cgit v1.2.3