use crate::ids::{BundleId, DeploymentId, PackId, RevisionId};
use crate::version::{SchemaVersion, SemVer};
use chrono::{DateTime, Utc};
use greentic_types::EnvId;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum RevisionLifecycle {
Inactive,
Staged,
Warming,
Ready,
Draining,
Failed,
Archived,
}
pub fn is_valid_transition(from: RevisionLifecycle, to: RevisionLifecycle) -> bool {
use RevisionLifecycle::*;
matches!(
(from, to),
(Inactive, Staged)
| (Inactive, Failed)
| (Inactive, Archived)
| (Staged, Warming)
| (Staged, Failed)
| (Staged, Archived)
| (Warming, Ready)
| (Warming, Failed)
| (Warming, Archived)
| (Ready, Draining)
| (Ready, Failed)
| (Ready, Archived)
| (Draining, Inactive)
| (Failed, Staged)
| (Failed, Archived)
)
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct PackListEntry {
pub pack_id: PackId,
pub version: SemVer,
pub digest: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub source_uri: Option<String>,
}
impl PackListEntry {
pub fn from_lock_primitives(pack_id: PackId, digest: String) -> Self {
Self {
pack_id,
version: SemVer::new(0, 0, 0),
digest,
source_uri: None,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Revision {
pub schema: SchemaVersion,
pub revision_id: RevisionId,
pub env_id: EnvId,
pub bundle_id: BundleId,
pub deployment_id: DeploymentId,
pub sequence: u64,
pub created_at: DateTime<Utc>,
pub bundle_digest: String,
pub pack_list: Vec<PackListEntry>,
pub pack_list_lock_ref: PathBuf,
#[serde(default)]
pub pack_config_refs: Vec<PathBuf>,
pub config_digest: String,
pub signature_sidecar_ref: PathBuf,
pub lifecycle: RevisionLifecycle,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub staged_at: Option<DateTime<Utc>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub warmed_at: Option<DateTime<Utc>>,
#[serde(default)]
pub drain_seconds: u32,
#[serde(default)]
pub abort_metrics: Vec<String>,
}
impl Revision {
pub fn schema_str() -> &'static str {
SchemaVersion::REVISION_V1
}
pub fn validate(&self) -> Result<(), crate::error::SpecError> {
if self.schema.as_str() != SchemaVersion::REVISION_V1 {
return Err(crate::error::SpecError::SchemaMismatch {
expected: SchemaVersion::REVISION_V1,
actual: self.schema.as_str().to_string(),
});
}
Ok(())
}
}