mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 12:11:56 +00:00
refactor logic around migrations to be more representative of reality
This commit is contained in:
committed by
Aiden McClelland
parent
e578062082
commit
351cef4141
@@ -935,8 +935,8 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin>(
|
||||
..
|
||||
} = prev
|
||||
{
|
||||
let mut configured = prev.status.configured;
|
||||
if let Some(res) = prev_manifest
|
||||
let prev_is_configured = prev.status.configured;
|
||||
let prev_migration = prev_manifest
|
||||
.migrations
|
||||
.to(
|
||||
ctx,
|
||||
@@ -945,14 +945,8 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin>(
|
||||
&prev_manifest.version,
|
||||
&prev_manifest.volumes,
|
||||
)
|
||||
.await?
|
||||
{
|
||||
configured &= res.configured;
|
||||
}
|
||||
if &prev.manifest.version != version {
|
||||
cleanup(ctx, &prev.manifest.id, &prev.manifest.version).await?;
|
||||
}
|
||||
if let Some(res) = manifest
|
||||
.map(futures::future::Either::Left);
|
||||
let migration = manifest
|
||||
.migrations
|
||||
.from(
|
||||
ctx,
|
||||
@@ -961,10 +955,20 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin>(
|
||||
version,
|
||||
&manifest.volumes,
|
||||
)
|
||||
.await?
|
||||
{
|
||||
configured &= res.configured;
|
||||
}
|
||||
.map(futures::future::Either::Right);
|
||||
|
||||
let viable_migration = if prev_manifest.version > manifest.version {
|
||||
prev_migration.or(migration)
|
||||
} else {
|
||||
migration.or(prev_migration)
|
||||
};
|
||||
|
||||
let configured = prev_is_configured
|
||||
&& if let Some(f) = viable_migration {
|
||||
f.await?.configured
|
||||
} else {
|
||||
false
|
||||
};
|
||||
if configured && manifest.config.is_some() {
|
||||
crate::config::configure(
|
||||
ctx,
|
||||
@@ -1002,6 +1006,9 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin>(
|
||||
.collect::<BTreeSet<_>>(),
|
||||
)
|
||||
.await?;
|
||||
if &prev.manifest.version != version {
|
||||
cleanup(ctx, &prev.manifest.id, &prev.manifest.version).await?;
|
||||
}
|
||||
} else if let PackageDataEntry::Restoring { .. } = prev {
|
||||
manifest
|
||||
.backup
|
||||
@@ -1051,12 +1058,12 @@ async fn handle_recovered_package(
|
||||
version: &Version,
|
||||
tx: &mut patch_db::Transaction<&mut patch_db::PatchDbHandle>,
|
||||
) -> Result<(), Error> {
|
||||
let configured = if let Some(res) = manifest
|
||||
.migrations
|
||||
.from(ctx, &recovered.version, pkg_id, version, &manifest.volumes)
|
||||
.await?
|
||||
let configured = if let Some(migration) =
|
||||
manifest
|
||||
.migrations
|
||||
.from(ctx, &recovered.version, pkg_id, version, &manifest.volumes)
|
||||
{
|
||||
res.configured
|
||||
migration.await?.configured
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use color_eyre::eyre::eyre;
|
||||
use emver::VersionRange;
|
||||
use futures::{Future, FutureExt, TryFutureExt};
|
||||
use indexmap::IndexMap;
|
||||
use patch_db::HasModel;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -20,76 +21,77 @@ pub struct Migrations {
|
||||
}
|
||||
impl Migrations {
|
||||
#[instrument(skip(ctx))]
|
||||
pub async fn from(
|
||||
&self,
|
||||
ctx: &RpcContext,
|
||||
version: &Version,
|
||||
pkg_id: &PackageId,
|
||||
pkg_version: &Version,
|
||||
volumes: &Volumes,
|
||||
) -> Result<Option<MigrationRes>, Error> {
|
||||
Ok(
|
||||
if let Some((_, migration)) = self
|
||||
.from
|
||||
.iter()
|
||||
.find(|(range, _)| version.satisfies(*range))
|
||||
{
|
||||
Some(
|
||||
migration
|
||||
.execute(
|
||||
ctx,
|
||||
pkg_id,
|
||||
pkg_version,
|
||||
Some("Migration"), // Migrations cannot be executed concurrently
|
||||
volumes,
|
||||
Some(version),
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.await?
|
||||
.map_err(|e| {
|
||||
Error::new(eyre!("{}", e.1), crate::ErrorKind::MigrationFailed)
|
||||
})?,
|
||||
)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
)
|
||||
pub fn from<'a>(
|
||||
&'a self,
|
||||
ctx: &'a RpcContext,
|
||||
version: &'a Version,
|
||||
pkg_id: &'a PackageId,
|
||||
pkg_version: &'a Version,
|
||||
volumes: &'a Volumes,
|
||||
) -> Option<impl Future<Output = Result<MigrationRes, Error>> + 'a> {
|
||||
if let Some((_, migration)) = self
|
||||
.from
|
||||
.iter()
|
||||
.find(|(range, _)| version.satisfies(*range))
|
||||
{
|
||||
Some(
|
||||
migration
|
||||
.execute(
|
||||
ctx,
|
||||
pkg_id,
|
||||
pkg_version,
|
||||
Some("Migration"), // Migrations cannot be executed concurrently
|
||||
volumes,
|
||||
Some(version),
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.map(|r| {
|
||||
r.and_then(|r| {
|
||||
r.map_err(|e| {
|
||||
Error::new(eyre!("{}", e.1), crate::ErrorKind::MigrationFailed)
|
||||
})
|
||||
})
|
||||
}),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(ctx))]
|
||||
pub async fn to(
|
||||
&self,
|
||||
ctx: &RpcContext,
|
||||
version: &Version,
|
||||
pkg_id: &PackageId,
|
||||
pkg_version: &Version,
|
||||
volumes: &Volumes,
|
||||
) -> Result<Option<MigrationRes>, Error> {
|
||||
Ok(
|
||||
if let Some((_, migration)) =
|
||||
self.to.iter().find(|(range, _)| version.satisfies(*range))
|
||||
{
|
||||
Some(
|
||||
migration
|
||||
.execute(
|
||||
ctx,
|
||||
pkg_id,
|
||||
pkg_version,
|
||||
Some("Migration"),
|
||||
volumes,
|
||||
Some(version),
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.await?
|
||||
.map_err(|e| {
|
||||
Error::new(eyre!("{}", e.1), crate::ErrorKind::MigrationFailed)
|
||||
})?,
|
||||
)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
)
|
||||
pub fn to<'a>(
|
||||
&'a self,
|
||||
ctx: &'a RpcContext,
|
||||
version: &'a Version,
|
||||
pkg_id: &'a PackageId,
|
||||
pkg_version: &'a Version,
|
||||
volumes: &'a Volumes,
|
||||
) -> Option<impl Future<Output = Result<MigrationRes, Error>> + 'a> {
|
||||
if let Some((_, migration)) = self.to.iter().find(|(range, _)| version.satisfies(*range)) {
|
||||
Some(
|
||||
migration
|
||||
.execute(
|
||||
ctx,
|
||||
pkg_id,
|
||||
pkg_version,
|
||||
Some("Migration"),
|
||||
volumes,
|
||||
Some(version),
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.map(|r| {
|
||||
r.and_then(|r| {
|
||||
r.map_err(|e| {
|
||||
Error::new(eyre!("{}", e.1), crate::ErrorKind::MigrationFailed)
|
||||
})
|
||||
})
|
||||
}),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user