mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
* wip * wip * wip * wip * wip * wip * remove debian dir * lazy env and git hash * remove env and git hash on clean * don't leave project dir * use docker for native builds * start9 rust * correctly mount registry * remove systemd config * switch to /usr/bin * disable sound for now * wip * change disk list * multi-arch images * multi-arch system images * default aarch64 * edition 2021 * dynamic wifi interface name * use wifi interface from config * bugfixes * add beep based sound * wip * wip * wip * separate out raspberry pi specific files * fixes * use new initramfs always * switch journald conf to sed script * fixes * fix permissions * talking about kernel modules not scripts * fix * fix * switch to MBR * install to /usr/lib * fixes * fixes * fixes * fixes * add media config to cfg path * fixes * fixes * fixes * raspi image fixes * fix test * fix workflow * sync boot partition * gahhhhh
140 lines
4.3 KiB
Rust
140 lines
4.3 KiB
Rust
use std::collections::BTreeSet;
|
|
|
|
use color_eyre::eyre::eyre;
|
|
use emver::VersionRange;
|
|
use futures::{Future, FutureExt};
|
|
use indexmap::IndexMap;
|
|
use patch_db::HasModel;
|
|
use serde::{Deserialize, Serialize};
|
|
use tracing::instrument;
|
|
|
|
use crate::context::RpcContext;
|
|
use crate::id::ImageId;
|
|
use crate::procedure::docker::DockerContainer;
|
|
use crate::procedure::{PackageProcedure, ProcedureName};
|
|
use crate::s9pk::manifest::PackageId;
|
|
use crate::util::Version;
|
|
use crate::volume::Volumes;
|
|
use crate::{Error, ResultExt};
|
|
|
|
#[derive(Clone, Debug, Default, Deserialize, Serialize, HasModel)]
|
|
#[serde(rename_all = "kebab-case")]
|
|
pub struct Migrations {
|
|
pub from: IndexMap<VersionRange, PackageProcedure>,
|
|
pub to: IndexMap<VersionRange, PackageProcedure>,
|
|
}
|
|
impl Migrations {
|
|
#[instrument]
|
|
pub fn validate(
|
|
&self,
|
|
container: &Option<DockerContainer>,
|
|
eos_version: &Version,
|
|
volumes: &Volumes,
|
|
image_ids: &BTreeSet<ImageId>,
|
|
) -> Result<(), Error> {
|
|
for (version, migration) in &self.from {
|
|
migration
|
|
.validate(container, eos_version, volumes, image_ids, true)
|
|
.with_ctx(|_| {
|
|
(
|
|
crate::ErrorKind::ValidateS9pk,
|
|
format!("Migration from {}", version),
|
|
)
|
|
})?;
|
|
}
|
|
for (version, migration) in &self.to {
|
|
migration
|
|
.validate(container, eos_version, volumes, image_ids, true)
|
|
.with_ctx(|_| {
|
|
(
|
|
crate::ErrorKind::ValidateS9pk,
|
|
format!("Migration to {}", version),
|
|
)
|
|
})?;
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
#[instrument(skip(ctx))]
|
|
pub fn from<'a>(
|
|
&'a self,
|
|
container: &'a Option<DockerContainer>,
|
|
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,
|
|
container,
|
|
pkg_id,
|
|
pkg_version,
|
|
ProcedureName::Migration, // Migrations cannot be executed concurrently
|
|
volumes,
|
|
Some(version),
|
|
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 fn to<'a>(
|
|
&'a self,
|
|
container: &'a Option<DockerContainer>,
|
|
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,
|
|
container,
|
|
pkg_id,
|
|
pkg_version,
|
|
ProcedureName::Migration,
|
|
volumes,
|
|
Some(version),
|
|
None,
|
|
)
|
|
.map(|r| {
|
|
r.and_then(|r| {
|
|
r.map_err(|e| {
|
|
Error::new(eyre!("{}", e.1), crate::ErrorKind::MigrationFailed)
|
|
})
|
|
})
|
|
}),
|
|
)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, Default, Deserialize, Serialize, HasModel)]
|
|
#[serde(rename_all = "kebab-case")]
|
|
pub struct MigrationRes {
|
|
pub configured: bool,
|
|
}
|