diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2021-01-15 23:16:18 +0100 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2021-01-15 23:16:18 +0100 |
commit | 4cf5a22ad1b0f5bf8f4e2c06c689ad40230e4387 (patch) | |
tree | b5b5ee7f0da306c86cf255a3bb61a7c55ccb43de | |
parent | 4ef85ea2d5584d673b5abc6723b6a8b3db8a48d3 (diff) | |
parent | 8c94e002e0ec2ea46d37e8ddf9a678fffe645d62 (diff) |
Merge branch 'released-artifacts'
-rw-r--r-- | migrations/2021-01-07-122618_dedicated-releases-table/down.sql | 7 | ||||
-rw-r--r-- | migrations/2021-01-07-122618_dedicated-releases-table/up.sql | 13 | ||||
-rw-r--r-- | src/commands/db.rs | 11 | ||||
-rw-r--r-- | src/commands/release.rs | 45 | ||||
-rw-r--r-- | src/db/models/artifact.rs | 10 | ||||
-rw-r--r-- | src/db/models/mod.rs | 3 | ||||
-rw-r--r-- | src/db/models/releases.rs | 44 | ||||
-rw-r--r-- | src/endpoint/scheduler.rs | 2 | ||||
-rw-r--r-- | src/schema.rs | 11 |
9 files changed, 117 insertions, 29 deletions
diff --git a/migrations/2021-01-07-122618_dedicated-releases-table/down.sql b/migrations/2021-01-07-122618_dedicated-releases-table/down.sql new file mode 100644 index 0000000..3eaa8b9 --- /dev/null +++ b/migrations/2021-01-07-122618_dedicated-releases-table/down.sql @@ -0,0 +1,7 @@ +-- This file should undo anything in `up.sql` +ALTER TABLE + artifacts +ADD COLUMN + released boolean NOT NULL; + +DROP TABLE releases; diff --git a/migrations/2021-01-07-122618_dedicated-releases-table/up.sql b/migrations/2021-01-07-122618_dedicated-releases-table/up.sql new file mode 100644 index 0000000..0fd2295 --- /dev/null +++ b/migrations/2021-01-07-122618_dedicated-releases-table/up.sql @@ -0,0 +1,13 @@ +-- Your SQL goes here +ALTER TABLE + artifacts +DROP COLUMN + released; + +CREATE TABLE releases ( + id SERIAL PRIMARY KEY NOT NULL, + artifact_id INTEGER REFERENCES artifacts(id) NOT NULL, + release_date TIMESTAMP WITH TIME ZONE NOT NULL, + + CONSTRAINT UC_art_release_unique UNIQUE (artifact_id, release_date) +); diff --git a/src/commands/db.rs b/src/commands/db.rs index 701f659..ed6360f 100644 --- a/src/commands/db.rs +++ b/src/commands/db.rs @@ -149,18 +149,23 @@ fn artifacts(conn_cfg: DbConnectionConfig, matches: &ArgMatches) -> Result<()> { .map(|job_uuid| -> Result<_> { dsl::artifacts .inner_join(schema::jobs::table) + .left_join(schema::releases::table) .filter(schema::jobs::dsl::uuid.eq(job_uuid)) - .load::<(models::Artifact, models::Job)>(&conn) + .load::<(models::Artifact, models::Job, Option<models::Release>)>(&conn) .map_err(Error::from) }) .unwrap_or_else(|| { dsl::artifacts .inner_join(schema::jobs::table) - .load::<(models::Artifact, models::Job)>(&conn) + .left_join(schema::releases::table) + .load::<(models::Artifact, models::Job, Option<models::Release>)>(&conn) .map_err(Error::from) })? .into_iter() - .map(|(artifact, job)| vec![format!("{}", artifact.id), artifact.path, artifact.released.to_string(), job.uuid.to_string()]) + .map(|(artifact, job, rel)| { + let rel = rel.map(|r| r.release_date.to_string()).unwrap_or_else(|| String::from("no")); + vec![format!("{}", artifact.id), artifact.path, rel, job.uuid.to_string()] + }) .collect::<Vec<_>>(); if data.is_empty() { diff --git a/src/commands/release.rs b/src/commands/release.rs index 723a779..b443ec1 100644 --- a/src/commands/release.rs +++ b/src/commands/release.rs @@ -55,35 +55,40 @@ pub async fn release(db_connection_config: DbConnectionConfig, config: &Configur .inner_join(crate::schema::packages::table) }) .filter(crate::schema::jobs::submit_id.eq(submit.id)) - .filter(crate::schema::artifacts::released.eq(false)); + .left_outer_join(crate::schema::releases::table) // not released + .select(crate::schema::artifacts::all_columns) + ; match (pname, pvers) { (Some(name), Some(vers)) => { - let query = sel.filter(crate::schema::packages::name.eq(name)) + let query = sel + .filter(crate::schema::packages::name.eq(name)) .filter(crate::schema::packages::version.like(vers)); - debug!("Query: {}", diesel::debug_query(&query).to_string()); - query.load::<(dbmodels::Artifact, (dbmodels::Job, dbmodels::Package))>(&conn)? + debug!("Query: {:?}", diesel::debug_query::<diesel::pg::Pg, _>(&query)); + query.load::<dbmodels::Artifact>(&conn)? }, (Some(name), None) => { - let query = sel.filter(crate::schema::packages::name.eq(name)); - debug!("Query: {}", diesel::debug_query(&query).to_string()); - query.load::<(dbmodels::Artifact, (dbmodels::Job, dbmodels::Package))>(&conn)? + let query = sel + .filter(crate::schema::packages::name.eq(name)); + debug!("Query: {:?}", diesel::debug_query::<diesel::pg::Pg, _>(&query)); + query.load::<dbmodels::Artifact>(&conn)? }, (None, Some(vers)) => { - let query = sel.filter(crate::schema::packages::version.like(vers)); - debug!("Query: {}", diesel::debug_query(&query).to_string()); - query.load::<(dbmodels::Artifact, (dbmodels::Job, dbmodels::Package))>(&conn)? + let query = sel + .filter(crate::schema::packages::version.like(vers)); + debug!("Query: {:?}", diesel::debug_query::<diesel::pg::Pg, _>(&query)); + query.load::<dbmodels::Artifact>(&conn)? }, (None, None) => { - debug!("Query: {}", diesel::debug_query(&sel).to_string()); - sel.load::<(dbmodels::Artifact, (dbmodels::Job, dbmodels::Package))>(&conn)? + debug!("Query: {:?}", diesel::debug_query::<diesel::pg::Pg, _>(&sel)); + sel.load::<dbmodels::Artifact>(&conn)? }, } }; debug!("Artifacts = {:?}", arts); arts.iter() - .filter_map(|(art, _)| art.path_buf().parent().map(|p| config.releases_directory().join(p))) + .filter_map(|art| art.path_buf().parent().map(|p| config.releases_directory().join(p))) .map(|p| async { debug!("mkdir {:?}", p); tokio::fs::create_dir_all(p).await.map_err(Error::from) @@ -93,8 +98,10 @@ pub async fn release(db_connection_config: DbConnectionConfig, config: &Configur .await?; let staging_base: &PathBuf = &config.staging_directory().join(submit.uuid.to_string()); + + let now = chrono::offset::Local::now().naive_local(); arts.into_iter() - .map(|(art, _)| async move { + .map(|art| async move { let art_path = staging_base.join(&art.path); let dest_path = config.releases_directory().join(&art.path); debug!("Trying to release {} to {}", art_path.display(), dest_path.display()); @@ -118,12 +125,10 @@ pub async fn release(db_connection_config: DbConnectionConfig, config: &Configur .await? .into_iter() .map(|art| { - debug!("Updating {:?} to set released = true", art); - diesel::update(&art) - .set(crate::schema::artifacts::released.eq(true)) - .execute(&conn) - .map(|_| ()) - .map_err(Error::from) + debug!("Creating Release object in database for {:?}", art); + let rel = crate::db::models::Release::create(&conn, &art, &now)?; + debug!("Release object = {:?}", rel); + Ok(()) }) .collect() } diff --git a/src/db/models/artifact.rs b/src/db/models/artifact.rs index 01de301..01ac4c7 100644 --- a/src/db/models/artifact.rs +++ b/src/db/models/artifact.rs @@ -15,6 +15,7 @@ use anyhow::anyhow; use anyhow::Error; use anyhow::Context; use anyhow::Result; +use chrono::NaiveDateTime; use diesel::PgConnection; use diesel::prelude::*; @@ -27,7 +28,6 @@ use crate::schema::artifacts; pub struct Artifact { pub id: i32, pub path: String, - pub released: bool, pub job_id: i32, } @@ -35,7 +35,6 @@ pub struct Artifact { #[table_name="artifacts"] struct NewArtifact<'a> { pub path: &'a str, - pub released: bool, pub job_id: i32, } @@ -44,13 +43,16 @@ impl Artifact { PathBuf::from(&self.path) } - pub fn create(database_connection: &PgConnection, art_path: &ArtifactPath, art_released: bool, job: &Job) -> Result<Artifact> { + pub fn released(self, database_connection: &PgConnection, release_date: &NaiveDateTime) -> Result<crate::db::models::Release> { + crate::db::models::Release::create(database_connection, &self, release_date) + } + + pub fn create(database_connection: &PgConnection, art_path: &ArtifactPath, job: &Job) -> Result<Artifact> { let path_str = art_path.to_str() .ok_or_else(|| anyhow!("Path is not valid UTF-8: {}", art_path.display())) .context("Writing artifact to database")?; let new_art = NewArtifact { path: path_str, - released: art_released, job_id: job.id, }; diff --git a/src/db/models/mod.rs b/src/db/models/mod.rs index cd7aa72..77ebc51 100644 --- a/src/db/models/mod.rs +++ b/src/db/models/mod.rs @@ -32,6 +32,9 @@ pub use githash::*; mod package; pub use package::*; +mod releases; +pub use releases::*; + mod submit; pub use submit::*; diff --git a/src/db/models/releases.rs b/src/db/models/releases.rs new file mode 100644 index 0000000..1975d2c --- /dev/null +++ b/src/db/models/releases.rs @@ -0,0 +1,44 @@ +use anyhow::Error; +use anyhow::Result; +use chrono::NaiveDateTime; +use diesel::PgConnection; +use diesel::prelude::*; + +use crate::db::models::Artifact; +use crate::schema::releases::*; +use crate::schema::releases; + +#[derive(Debug, Identifiable, Queryable, Associations)] +#[belongs_to(Artifact)] +pub struct Release { + pub id: i32, + pub artifact_id: i32, + pub release_date: NaiveDateTime, +} + +#[derive(Insertable)] +#[table_name="releases"] +struct NewRelease<'a> { + pub artifact_id: i32, + pub release_date: &'a NaiveDateTime, +} + +impl Release { + pub fn create<'a>(database_connection: &PgConnection, art: &Artifact, date: &'a NaiveDateTime) -> Result<Release> { + let new_rel = NewRelease { + artifact_id: art.id, + release_date: date, + }; + + diesel::insert_into(releases::table) + .values(&new_rel) + .execute(database_connection)?; + + dsl::releases + .filter(artifact_id.eq(art.id).and(release_date.eq(date))) + .first::<Release>(database_connection) + .map_err(Error::from) + } +} + + diff --git a/src/endpoint/scheduler.rs b/src/endpoint/scheduler.rs index 1286ca9..0ed13cb 100644 --- a/src/endpoint/scheduler.rs +++ b/src/endpoint/scheduler.rs @@ -190,7 +190,7 @@ impl JobHandle { let mut r = vec![]; for p in paths.iter() { trace!("DB: Creating artifact entry for path: {}", p.display()); - r.push(dbmodels::Artifact::create(&self.db, p, false, &job)?); + r.push(dbmodels::Artifact::create(&self.db, p, &job)?); } Ok(r) } diff --git a/src/schema.rs b/src/schema.rs index 85e9266..7aac78a 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -12,7 +12,6 @@ table! { artifacts (id) { id -> Int4, path -> Varchar, - released -> Bool, job_id -> Int4, } } @@ -93,6 +92,14 @@ table! { } table! { + releases (id) { + id -> Int4, + artifact_id -> Int4, + release_date -> Timestamptz, + } +} + +table! { submit_envs (id) { id -> Int4, submit_id -> Int4, @@ -123,6 +130,7 @@ joinable!(jobs -> endpoints (endpoint_id)); joinable!(jobs -> images (image_id)); joinable!(jobs -> packages (package_id)); joinable!(jobs -> submits (submit_id)); +joinable!(releases -> artifacts (artifact_id)); joinable!(submit_envs -> envvars (env_id)); joinable!(submit_envs -> submits (submit_id)); joinable!(submits -> githashes (repo_hash_id)); @@ -140,6 +148,7 @@ allow_tables_to_appear_in_same_query!( job_output_artifacts, jobs, packages, + releases, submit_envs, submits, ); |