create version graph to handle migrations (#2708)

* create version graph to handle migrations

* Fix some version alpha test

* connect dataVersion api

* rename init fns

* improve types and add tests

* set data version after backup restore

* chore: Add some types tests for version info

* wip: More changes to versionInfo tests

* wip: fix my stupid

* update mocks

* update runtime

* chore: Fix the loop

---------

Co-authored-by: Jade <2364004+Blu-J@users.noreply.github.com>
Co-authored-by: J H <dragondef@gmail.com>
This commit is contained in:
Aiden McClelland
2024-08-15 20:58:53 +00:00
committed by GitHub
parent c704626a39
commit c174b65465
34 changed files with 974 additions and 257 deletions

View File

@@ -3,7 +3,9 @@ use std::collections::{BTreeMap, BTreeSet};
use chrono::{DateTime, Utc};
use exver::VersionRange;
use imbl_value::InternedString;
use models::{ActionId, DataUrl, HealthCheckId, HostId, PackageId, ServiceInterfaceId};
use models::{
ActionId, DataUrl, HealthCheckId, HostId, PackageId, ServiceInterfaceId, VersionString,
};
use patch_db::json_ptr::JsonPointer;
use patch_db::HasModel;
use reqwest::Url;
@@ -335,6 +337,7 @@ pub struct ActionMetadata {
#[ts(export)]
pub struct PackageDataEntry {
pub state_info: PackageState,
pub data_version: Option<VersionString>,
pub status: Status,
#[ts(type = "string | null")]
pub registry: Option<Url>,

View File

@@ -2,7 +2,7 @@ use std::collections::{BTreeMap, BTreeSet};
use std::path::Path;
use std::sync::Arc;
use exver::ExtendedVersion;
use exver::{ExtendedVersion, VersionRange};
use models::ImageId;
use tokio::io::{AsyncRead, AsyncSeek, AsyncWriteExt};
use tokio::process::Command;
@@ -203,6 +203,8 @@ impl From<ManifestV1> for Manifest {
version: ExtendedVersion::from(value.version).into(),
satisfies: BTreeSet::new(),
release_notes: value.release_notes,
can_migrate_from: VersionRange::any(),
can_migrate_to: VersionRange::none(),
license: value.license.into(),
wrapper_repo: value.wrapper_repo,
upstream_repo: value.upstream_repo,

View File

@@ -2,7 +2,7 @@ use std::collections::{BTreeMap, BTreeSet};
use std::path::Path;
use color_eyre::eyre::eyre;
use exver::Version;
use exver::{Version, VersionRange};
use helpers::const_true;
use imbl_value::InternedString;
pub use models::PackageId;
@@ -37,6 +37,10 @@ pub struct Manifest {
pub satisfies: BTreeSet<VersionString>,
pub release_notes: String,
#[ts(type = "string")]
pub can_migrate_to: VersionRange,
#[ts(type = "string")]
pub can_migrate_from: VersionRange,
#[ts(type = "string")]
pub license: InternedString, // type of license
#[ts(type = "string")]
pub wrapper_repo: Url,
@@ -159,8 +163,8 @@ impl Manifest {
#[ts(export)]
pub struct HardwareRequirements {
#[serde(default)]
#[ts(type = "{ device?: string, processor?: string }")]
pub device: BTreeMap<String, Regex>,
#[ts(type = "{ display?: string, processor?: string }")]
pub device: BTreeMap<String, Regex>, // TODO: array
#[ts(type = "number | null")]
pub ram: Option<u64>,
#[ts(type = "string[] | null")]

View File

@@ -164,6 +164,25 @@ pub fn handler<C: Context>() -> ParentHandler<C> {
// store
.subcommand("getStore", from_fn_async(store::get_store).no_cli())
.subcommand("setStore", from_fn_async(store::set_store).no_cli())
.subcommand(
"setDataVersion",
from_fn_async(store::set_data_version)
.no_display()
.with_call_remote::<ContainerCliContext>(),
)
.subcommand(
"getDataVersion",
from_fn_async(store::get_data_version)
.with_custom_display_fn(|_, v| {
if let Some(v) = v {
println!("{v}")
} else {
println!("N/A")
}
Ok(())
})
.with_call_remote::<ContainerCliContext>(),
)
// system
.subcommand(
"getSystemSmtp",

View File

@@ -1,6 +1,6 @@
use imbl::vector;
use imbl_value::json;
use models::PackageId;
use models::{PackageId, VersionString};
use patch_db::json_ptr::JsonPointer;
use crate::service::effects::callbacks::CallbackHandler;
@@ -91,3 +91,50 @@ pub async fn set_store(
Ok(())
}
#[derive(Debug, Clone, Serialize, Deserialize, TS, Parser)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct SetDataVersionParams {
#[ts(type = "string")]
version: VersionString,
}
pub async fn set_data_version(
context: EffectContext,
SetDataVersionParams { version }: SetDataVersionParams,
) -> Result<(), Error> {
let context = context.deref()?;
let package_id = &context.seed.id;
context
.seed
.ctx
.db
.mutate(|db| {
db.as_public_mut()
.as_package_data_mut()
.as_idx_mut(package_id)
.or_not_found(package_id)?
.as_data_version_mut()
.ser(&Some(version))
})
.await?;
Ok(())
}
pub async fn get_data_version(context: EffectContext) -> Result<Option<VersionString>, Error> {
let context = context.deref()?;
let package_id = &context.seed.id;
context
.seed
.ctx
.db
.peek()
.await
.as_public()
.as_package_data()
.as_idx(package_id)
.or_not_found(package_id)?
.as_data_version()
.de()
}

View File

@@ -173,6 +173,7 @@ impl ServiceMap {
} else {
PackageState::Installing(installing)
},
data_version: None,
status: Status {
configured: false,
main: MainStatus::Stopped,