mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 20:14:49 +00:00
Feature/remove postgres (#2570)
* wip: move postgres data to patchdb * wip * wip * wip * complete notifications and clean up warnings * fill in user agent * move os tor bindings to single call
This commit is contained in:
@@ -1,33 +1,25 @@
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use color_eyre::eyre::eyre;
|
||||
use futures::Future;
|
||||
use imbl_value::InternedString;
|
||||
use sqlx::PgPool;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::Error;
|
||||
|
||||
mod v0_3_4;
|
||||
mod v0_3_4_1;
|
||||
mod v0_3_4_2;
|
||||
mod v0_3_4_3;
|
||||
mod v0_3_4_4;
|
||||
mod v0_3_5;
|
||||
mod v0_3_5_1;
|
||||
mod v0_3_6;
|
||||
|
||||
pub type Current = v0_3_5_1::Version;
|
||||
pub type Current = v0_3_6::Version;
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
#[serde(untagged)]
|
||||
enum Version {
|
||||
V0_3_4(Wrapper<v0_3_4::Version>),
|
||||
V0_3_4_1(Wrapper<v0_3_4_1::Version>),
|
||||
V0_3_4_2(Wrapper<v0_3_4_2::Version>),
|
||||
V0_3_4_3(Wrapper<v0_3_4_3::Version>),
|
||||
V0_3_4_4(Wrapper<v0_3_4_4::Version>),
|
||||
LT0_3_5(LTWrapper<v0_3_5::Version>),
|
||||
V0_3_5(Wrapper<v0_3_5::Version>),
|
||||
V0_3_5_1(Wrapper<v0_3_5_1::Version>),
|
||||
V0_3_6(Wrapper<v0_3_6::Version>),
|
||||
Other(emver::Version),
|
||||
}
|
||||
|
||||
@@ -43,19 +35,15 @@ impl Version {
|
||||
#[cfg(test)]
|
||||
fn as_sem_ver(&self) -> emver::Version {
|
||||
match self {
|
||||
Version::V0_3_4(Wrapper(x)) => x.semver(),
|
||||
Version::V0_3_4_1(Wrapper(x)) => x.semver(),
|
||||
Version::V0_3_4_2(Wrapper(x)) => x.semver(),
|
||||
Version::V0_3_4_3(Wrapper(x)) => x.semver(),
|
||||
Version::V0_3_4_4(Wrapper(x)) => x.semver(),
|
||||
Version::LT0_3_5(LTWrapper(_, x)) => x.clone(),
|
||||
Version::V0_3_5(Wrapper(x)) => x.semver(),
|
||||
Version::V0_3_5_1(Wrapper(x)) => x.semver(),
|
||||
Version::V0_3_6(Wrapper(x)) => x.semver(),
|
||||
Version::Other(x) => x.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait VersionT
|
||||
where
|
||||
Self: Sized + Send + Sync,
|
||||
@@ -64,86 +52,115 @@ where
|
||||
fn new() -> Self;
|
||||
fn semver(&self) -> emver::Version;
|
||||
fn compat(&self) -> &'static emver::VersionRange;
|
||||
async fn up(&self, db: PatchDb, secrets: &PgPool) -> Result<(), Error>;
|
||||
async fn down(&self, db: PatchDb, secrets: &PgPool) -> Result<(), Error>;
|
||||
async fn commit(&self, db: PatchDb) -> Result<(), Error> {
|
||||
let semver = self.semver().into();
|
||||
let compat = self.compat().clone();
|
||||
db.mutate(|d| {
|
||||
d.as_public_mut()
|
||||
.as_server_info_mut()
|
||||
.as_version_mut()
|
||||
.ser(&semver)?;
|
||||
d.as_public_mut()
|
||||
.as_server_info_mut()
|
||||
.as_eos_version_compat_mut()
|
||||
.ser(&compat)?;
|
||||
fn up(&self, db: &PatchDb) -> impl Future<Output = Result<(), Error>> + Send;
|
||||
fn down(&self, db: &PatchDb) -> impl Future<Output = Result<(), Error>> + Send;
|
||||
fn commit(&self, db: &PatchDb) -> impl Future<Output = Result<(), Error>> + Send {
|
||||
async {
|
||||
let semver = self.semver().into();
|
||||
let compat = self.compat().clone();
|
||||
db.mutate(|d| {
|
||||
d.as_public_mut()
|
||||
.as_server_info_mut()
|
||||
.as_version_mut()
|
||||
.ser(&semver)?;
|
||||
d.as_public_mut()
|
||||
.as_server_info_mut()
|
||||
.as_eos_version_compat_mut()
|
||||
.ser(&compat)?;
|
||||
Ok(())
|
||||
})
|
||||
.await?;
|
||||
Ok(())
|
||||
})
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
async fn migrate_to<V: VersionT>(
|
||||
&self,
|
||||
version: &V,
|
||||
db: PatchDb,
|
||||
secrets: &PgPool,
|
||||
) -> Result<(), Error> {
|
||||
match self.semver().cmp(&version.semver()) {
|
||||
Ordering::Greater => self.rollback_to_unchecked(version, db, secrets).await,
|
||||
Ordering::Less => version.migrate_from_unchecked(self, db, secrets).await,
|
||||
Ordering::Equal => Ok(()),
|
||||
}
|
||||
}
|
||||
async fn migrate_from_unchecked<V: VersionT>(
|
||||
fn migrate_to<V: VersionT>(
|
||||
&self,
|
||||
version: &V,
|
||||
db: PatchDb,
|
||||
secrets: &PgPool,
|
||||
) -> Result<(), Error> {
|
||||
let previous = Self::Previous::new();
|
||||
if version.semver() < previous.semver() {
|
||||
previous
|
||||
.migrate_from_unchecked(version, db.clone(), secrets)
|
||||
.await?;
|
||||
} else if version.semver() > previous.semver() {
|
||||
return Err(Error::new(
|
||||
eyre!(
|
||||
"NO PATH FROM {}, THIS IS LIKELY A MISTAKE IN THE VERSION DEFINITION",
|
||||
version.semver()
|
||||
),
|
||||
crate::ErrorKind::MigrationFailed,
|
||||
));
|
||||
db: &PatchDb,
|
||||
) -> impl Future<Output = Result<(), Error>> + Send {
|
||||
async {
|
||||
match self.semver().cmp(&version.semver()) {
|
||||
Ordering::Greater => self.rollback_to_unchecked(version, db).await,
|
||||
Ordering::Less => version.migrate_from_unchecked(self, db).await,
|
||||
Ordering::Equal => Ok(()),
|
||||
}
|
||||
}
|
||||
tracing::info!("{} -> {}", previous.semver(), self.semver(),);
|
||||
self.up(db.clone(), secrets).await?;
|
||||
self.commit(db).await?;
|
||||
Ok(())
|
||||
}
|
||||
async fn rollback_to_unchecked<V: VersionT>(
|
||||
fn migrate_from_unchecked<V: VersionT>(
|
||||
&self,
|
||||
version: &V,
|
||||
db: PatchDb,
|
||||
secrets: &PgPool,
|
||||
) -> Result<(), Error> {
|
||||
let previous = Self::Previous::new();
|
||||
tracing::info!("{} -> {}", self.semver(), previous.semver(),);
|
||||
self.down(db.clone(), secrets).await?;
|
||||
previous.commit(db.clone()).await?;
|
||||
if version.semver() < previous.semver() {
|
||||
previous.rollback_to_unchecked(version, db, secrets).await?;
|
||||
} else if version.semver() > previous.semver() {
|
||||
return Err(Error::new(
|
||||
eyre!(
|
||||
"NO PATH TO {}, THIS IS LIKELY A MISTAKE IN THE VERSION DEFINITION",
|
||||
version.semver()
|
||||
),
|
||||
crate::ErrorKind::MigrationFailed,
|
||||
));
|
||||
db: &PatchDb,
|
||||
) -> impl Future<Output = Result<(), Error>> + Send {
|
||||
async {
|
||||
let previous = Self::Previous::new();
|
||||
if version.semver() < previous.semver() {
|
||||
previous.migrate_from_unchecked(version, db).await?;
|
||||
} else if version.semver() > previous.semver() {
|
||||
return Err(Error::new(
|
||||
eyre!(
|
||||
"NO PATH FROM {}, THIS IS LIKELY A MISTAKE IN THE VERSION DEFINITION",
|
||||
version.semver()
|
||||
),
|
||||
crate::ErrorKind::MigrationFailed,
|
||||
));
|
||||
}
|
||||
tracing::info!("{} -> {}", previous.semver(), self.semver(),);
|
||||
self.up(db).await?;
|
||||
self.commit(db).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
fn rollback_to_unchecked<V: VersionT>(
|
||||
&self,
|
||||
version: &V,
|
||||
db: &PatchDb,
|
||||
) -> impl Future<Output = Result<(), Error>> + Send {
|
||||
async {
|
||||
let previous = Self::Previous::new();
|
||||
tracing::info!("{} -> {}", self.semver(), previous.semver(),);
|
||||
self.down(db).await?;
|
||||
previous.commit(db).await?;
|
||||
if version.semver() < previous.semver() {
|
||||
previous.rollback_to_unchecked(version, db).await?;
|
||||
} else if version.semver() > previous.semver() {
|
||||
return Err(Error::new(
|
||||
eyre!(
|
||||
"NO PATH TO {}, THIS IS LIKELY A MISTAKE IN THE VERSION DEFINITION",
|
||||
version.semver()
|
||||
),
|
||||
crate::ErrorKind::MigrationFailed,
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct LTWrapper<T>(T, emver::Version);
|
||||
impl<T> serde::Serialize for LTWrapper<T>
|
||||
where
|
||||
T: VersionT,
|
||||
{
|
||||
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
self.0.semver().serialize(serializer)
|
||||
}
|
||||
}
|
||||
impl<'de, T> serde::Deserialize<'de> for LTWrapper<T>
|
||||
where
|
||||
T: VersionT,
|
||||
{
|
||||
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
||||
let v = crate::util::Version::deserialize(deserializer)?;
|
||||
let version = T::new();
|
||||
if *v < version.semver() {
|
||||
Ok(Self(version, v.into_version()))
|
||||
} else {
|
||||
Err(serde::de::Error::custom("Mismatched Version"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Wrapper<T>(T);
|
||||
impl<T> serde::Serialize for Wrapper<T>
|
||||
@@ -169,7 +186,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn init(db: &PatchDb, secrets: &PgPool) -> Result<(), Error> {
|
||||
pub async fn init(db: &PatchDb) -> Result<(), Error> {
|
||||
let version = Version::from_util_version(
|
||||
db.peek()
|
||||
.await
|
||||
@@ -180,13 +197,15 @@ pub async fn init(db: &PatchDb, secrets: &PgPool) -> Result<(), Error> {
|
||||
);
|
||||
|
||||
match version {
|
||||
Version::V0_3_4(v) => v.0.migrate_to(&Current::new(), db.clone(), secrets).await?,
|
||||
Version::V0_3_4_1(v) => v.0.migrate_to(&Current::new(), db.clone(), secrets).await?,
|
||||
Version::V0_3_4_2(v) => v.0.migrate_to(&Current::new(), db.clone(), secrets).await?,
|
||||
Version::V0_3_4_3(v) => v.0.migrate_to(&Current::new(), db.clone(), secrets).await?,
|
||||
Version::V0_3_4_4(v) => v.0.migrate_to(&Current::new(), db.clone(), secrets).await?,
|
||||
Version::V0_3_5(v) => v.0.migrate_to(&Current::new(), db.clone(), secrets).await?,
|
||||
Version::V0_3_5_1(v) => v.0.migrate_to(&Current::new(), db.clone(), secrets).await?,
|
||||
Version::LT0_3_5(_) => {
|
||||
return Err(Error::new(
|
||||
eyre!("Cannot migrate from pre-0.3.5. Please update to v0.3.5 first."),
|
||||
ErrorKind::MigrationFailed,
|
||||
));
|
||||
}
|
||||
Version::V0_3_5(v) => v.0.migrate_to(&Current::new(), &db).await?,
|
||||
Version::V0_3_5_1(v) => v.0.migrate_to(&Current::new(), &db).await?,
|
||||
Version::V0_3_6(v) => v.0.migrate_to(&Current::new(), &db).await?,
|
||||
Version::Other(_) => {
|
||||
return Err(Error::new(
|
||||
eyre!("Cannot downgrade"),
|
||||
@@ -218,11 +237,6 @@ mod tests {
|
||||
|
||||
fn versions() -> impl Strategy<Value = Version> {
|
||||
prop_oneof![
|
||||
Just(Version::V0_3_4(Wrapper(v0_3_4::Version::new()))),
|
||||
Just(Version::V0_3_4_1(Wrapper(v0_3_4_1::Version::new()))),
|
||||
Just(Version::V0_3_4_2(Wrapper(v0_3_4_2::Version::new()))),
|
||||
Just(Version::V0_3_4_3(Wrapper(v0_3_4_3::Version::new()))),
|
||||
Just(Version::V0_3_4_4(Wrapper(v0_3_4_4::Version::new()))),
|
||||
Just(Version::V0_3_5(Wrapper(v0_3_5::Version::new()))),
|
||||
Just(Version::V0_3_5_1(Wrapper(v0_3_5_1::Version::new()))),
|
||||
em_version().prop_map(Version::Other),
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
use async_trait::async_trait;
|
||||
use emver::VersionRange;
|
||||
use itertools::Itertools;
|
||||
use openssl::hash::MessageDigest;
|
||||
use serde_json::json;
|
||||
use ssh_key::public::Ed25519PublicKey;
|
||||
|
||||
use super::*;
|
||||
use crate::account::AccountInfo;
|
||||
use crate::hostname::{sync_hostname, Hostname};
|
||||
use crate::prelude::*;
|
||||
|
||||
const V0_3_4: emver::Version = emver::Version::new(0, 3, 4, 0);
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
pub static ref V0_3_0_COMPAT: VersionRange = VersionRange::Conj(
|
||||
Box::new(VersionRange::Anchor(
|
||||
emver::GTE,
|
||||
emver::Version::new(0, 3, 0, 0),
|
||||
)),
|
||||
Box::new(VersionRange::Anchor(emver::LTE, Current::new().semver())),
|
||||
);
|
||||
}
|
||||
|
||||
const COMMUNITY_URL: &str = "https://community-registry.start9.com/";
|
||||
const MAIN_REGISTRY: &str = "https://registry.start9.com/";
|
||||
const COMMUNITY_SERVICES: &[&str] = &[
|
||||
"ipfs",
|
||||
"agora",
|
||||
"lightning-jet",
|
||||
"balanceofsatoshis",
|
||||
"mastodon",
|
||||
"lndg",
|
||||
"robosats",
|
||||
"thunderhub",
|
||||
"syncthing",
|
||||
"sphinx-relay",
|
||||
];
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Version;
|
||||
|
||||
#[async_trait]
|
||||
impl VersionT for Version {
|
||||
type Previous = Self;
|
||||
fn new() -> Self {
|
||||
Version
|
||||
}
|
||||
fn semver(&self) -> emver::Version {
|
||||
V0_3_4
|
||||
}
|
||||
fn compat(&self) -> &'static VersionRange {
|
||||
&*V0_3_0_COMPAT
|
||||
}
|
||||
async fn up(&self, db: PatchDb, secrets: &PgPool) -> Result<(), Error> {
|
||||
let mut account = AccountInfo::load(secrets).await?;
|
||||
let account = db
|
||||
.mutate(|d| {
|
||||
d.as_public_mut().as_server_info_mut().as_pubkey_mut().ser(
|
||||
&ssh_key::PublicKey::from(Ed25519PublicKey::from(&account.key.ssh_key()))
|
||||
.to_openssh()?,
|
||||
)?;
|
||||
d.as_public_mut()
|
||||
.as_server_info_mut()
|
||||
.as_ca_fingerprint_mut()
|
||||
.ser(
|
||||
&account
|
||||
.root_ca_cert
|
||||
.digest(MessageDigest::sha256())
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|x| format!("{x:X}"))
|
||||
.join(":"),
|
||||
)?;
|
||||
let server_info = d.as_public_mut().as_server_info();
|
||||
account.hostname = server_info.as_hostname().de().map(Hostname)?;
|
||||
account.server_id = server_info.as_id().de()?;
|
||||
|
||||
Ok(account)
|
||||
})
|
||||
.await?;
|
||||
account.save(secrets).await?;
|
||||
sync_hostname(&account.hostname).await?;
|
||||
|
||||
let parsed_url = Some(COMMUNITY_URL.parse().unwrap());
|
||||
db.mutate(|d| {
|
||||
let mut ui = d.as_public().as_ui().de()?;
|
||||
use imbl_value::json;
|
||||
ui["marketplace"]["known-hosts"][COMMUNITY_URL] = json!({});
|
||||
ui["marketplace"]["known-hosts"][MAIN_REGISTRY] = json!({});
|
||||
for package_id in d.as_public().as_package_data().keys()? {
|
||||
if !COMMUNITY_SERVICES.contains(&&*package_id.to_string()) {
|
||||
continue;
|
||||
}
|
||||
d.as_public_mut()
|
||||
.as_package_data_mut()
|
||||
.as_idx_mut(&package_id)
|
||||
.or_not_found(&package_id)?
|
||||
.as_installed_mut()
|
||||
.or_not_found(&package_id)?
|
||||
.as_marketplace_url_mut()
|
||||
.ser(&parsed_url)?;
|
||||
}
|
||||
ui["theme"] = json!("Dark".to_string());
|
||||
ui["widgets"] = json!([]);
|
||||
|
||||
d.as_public_mut().as_ui_mut().ser(&ui)
|
||||
})
|
||||
.await
|
||||
}
|
||||
async fn down(&self, db: PatchDb, _secrets: &PgPool) -> Result<(), Error> {
|
||||
db.mutate(|d| {
|
||||
let mut ui = d.as_public().as_ui().de()?;
|
||||
let parsed_url = Some(MAIN_REGISTRY.parse().unwrap());
|
||||
for package_id in d.as_public().as_package_data().keys()? {
|
||||
if !COMMUNITY_SERVICES.contains(&&*package_id.to_string()) {
|
||||
continue;
|
||||
}
|
||||
d.as_public_mut()
|
||||
.as_package_data_mut()
|
||||
.as_idx_mut(&package_id)
|
||||
.or_not_found(&package_id)?
|
||||
.as_installed_mut()
|
||||
.or_not_found(&package_id)?
|
||||
.as_marketplace_url_mut()
|
||||
.ser(&parsed_url)?;
|
||||
}
|
||||
|
||||
if let imbl_value::Value::Object(ref mut obj) = ui {
|
||||
obj.remove("theme");
|
||||
obj.remove("widgets");
|
||||
}
|
||||
|
||||
ui["marketplace"]["known-hosts"][COMMUNITY_URL].take();
|
||||
ui["marketplace"]["known-hosts"][MAIN_REGISTRY].take();
|
||||
d.as_public_mut().as_ui_mut().ser(&ui)
|
||||
})
|
||||
.await
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
use async_trait::async_trait;
|
||||
use emver::VersionRange;
|
||||
|
||||
use super::v0_3_4::V0_3_0_COMPAT;
|
||||
use super::*;
|
||||
use crate::prelude::*;
|
||||
|
||||
const V0_3_4_1: emver::Version = emver::Version::new(0, 3, 4, 1);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Version;
|
||||
|
||||
#[async_trait]
|
||||
impl VersionT for Version {
|
||||
type Previous = v0_3_4::Version;
|
||||
fn new() -> Self {
|
||||
Version
|
||||
}
|
||||
fn semver(&self) -> emver::Version {
|
||||
V0_3_4_1
|
||||
}
|
||||
fn compat(&self) -> &'static VersionRange {
|
||||
&*V0_3_0_COMPAT
|
||||
}
|
||||
async fn up(&self, _db: PatchDb, _secrets: &PgPool) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
async fn down(&self, _db: PatchDb, _secrets: &PgPool) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
use async_trait::async_trait;
|
||||
use emver::VersionRange;
|
||||
|
||||
use super::v0_3_4::V0_3_0_COMPAT;
|
||||
use super::*;
|
||||
use crate::prelude::*;
|
||||
|
||||
const V0_3_4_2: emver::Version = emver::Version::new(0, 3, 4, 2);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Version;
|
||||
|
||||
#[async_trait]
|
||||
impl VersionT for Version {
|
||||
type Previous = v0_3_4_1::Version;
|
||||
fn new() -> Self {
|
||||
Version
|
||||
}
|
||||
fn semver(&self) -> emver::Version {
|
||||
V0_3_4_2
|
||||
}
|
||||
fn compat(&self) -> &'static VersionRange {
|
||||
&*V0_3_0_COMPAT
|
||||
}
|
||||
async fn up(&self, _db: PatchDb, _secrets: &PgPool) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
async fn down(&self, _db: PatchDb, _secrets: &PgPool) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
use async_trait::async_trait;
|
||||
use emver::VersionRange;
|
||||
|
||||
use super::v0_3_4::V0_3_0_COMPAT;
|
||||
use super::*;
|
||||
use crate::prelude::*;
|
||||
|
||||
const V0_3_4_3: emver::Version = emver::Version::new(0, 3, 4, 3);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Version;
|
||||
|
||||
#[async_trait]
|
||||
impl VersionT for Version {
|
||||
type Previous = v0_3_4_2::Version;
|
||||
fn new() -> Self {
|
||||
Version
|
||||
}
|
||||
fn semver(&self) -> emver::Version {
|
||||
V0_3_4_3
|
||||
}
|
||||
fn compat(&self) -> &'static VersionRange {
|
||||
&V0_3_0_COMPAT
|
||||
}
|
||||
async fn up(&self, _db: PatchDb, _secrets: &PgPool) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
async fn down(&self, _db: PatchDb, _secrets: &PgPool) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
use async_trait::async_trait;
|
||||
use emver::VersionRange;
|
||||
use models::ResultExt;
|
||||
use sqlx::PgPool;
|
||||
|
||||
use super::v0_3_4::V0_3_0_COMPAT;
|
||||
use super::{v0_3_4_3, VersionT};
|
||||
use crate::prelude::*;
|
||||
|
||||
const V0_3_4_4: emver::Version = emver::Version::new(0, 3, 4, 4);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Version;
|
||||
|
||||
#[async_trait]
|
||||
impl VersionT for Version {
|
||||
type Previous = v0_3_4_3::Version;
|
||||
fn new() -> Self {
|
||||
Version
|
||||
}
|
||||
fn semver(&self) -> emver::Version {
|
||||
V0_3_4_4
|
||||
}
|
||||
fn compat(&self) -> &'static VersionRange {
|
||||
&V0_3_0_COMPAT
|
||||
}
|
||||
async fn up(&self, db: PatchDb, _secrets: &PgPool) -> Result<(), Error> {
|
||||
db.mutate(|v| {
|
||||
let tor_address_lens = v.as_public_mut().as_server_info_mut().as_tor_address_mut();
|
||||
let mut tor_addr = tor_address_lens.de()?;
|
||||
tor_addr
|
||||
.set_scheme("https")
|
||||
.map_err(|_| eyre!("unable to update url scheme to https"))
|
||||
.with_kind(crate::ErrorKind::ParseUrl)?;
|
||||
tor_address_lens.ser(&tor_addr)
|
||||
})
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
async fn down(&self, _db: PatchDb, _secrets: &PgPool) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,26 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::path::Path;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use emver::VersionRange;
|
||||
use models::DataUrl;
|
||||
use sqlx::PgPool;
|
||||
|
||||
use super::v0_3_4::V0_3_0_COMPAT;
|
||||
use super::{v0_3_4_4, VersionT};
|
||||
use super::VersionT;
|
||||
use crate::prelude::*;
|
||||
use crate::version::Current;
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
pub static ref V0_3_0_COMPAT: VersionRange = VersionRange::Conj(
|
||||
Box::new(VersionRange::Anchor(
|
||||
emver::GTE,
|
||||
emver::Version::new(0, 3, 0, 0),
|
||||
)),
|
||||
Box::new(VersionRange::Anchor(emver::LTE, Current::new().semver())),
|
||||
);
|
||||
}
|
||||
|
||||
const V0_3_5: emver::Version = emver::Version::new(0, 3, 5, 0);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Version;
|
||||
|
||||
#[async_trait]
|
||||
impl VersionT for Version {
|
||||
type Previous = v0_3_4_4::Version;
|
||||
type Previous = Self;
|
||||
fn new() -> Self {
|
||||
Version
|
||||
}
|
||||
@@ -27,86 +30,10 @@ impl VersionT for Version {
|
||||
fn compat(&self) -> &'static VersionRange {
|
||||
&V0_3_0_COMPAT
|
||||
}
|
||||
async fn up(&self, db: PatchDb, _secrets: &PgPool) -> Result<(), Error> {
|
||||
let peek = db.peek().await;
|
||||
let mut url_replacements = BTreeMap::new();
|
||||
for (_, pde) in peek.as_public().as_package_data().as_entries()? {
|
||||
for (dependency, info) in pde
|
||||
.as_installed()
|
||||
.map(|i| i.as_dependency_info().as_entries())
|
||||
.transpose()?
|
||||
.into_iter()
|
||||
.flatten()
|
||||
{
|
||||
if !url_replacements.contains_key(&dependency) {
|
||||
url_replacements.insert(
|
||||
dependency,
|
||||
DataUrl::from_path(
|
||||
<&Value>::from(info.as_icon())
|
||||
.as_str()
|
||||
.and_then(|i| i.strip_prefix("/public/package-data/"))
|
||||
.map(|path| {
|
||||
Path::new("/embassy-data/package-data/public").join(path)
|
||||
})
|
||||
.unwrap_or_default(),
|
||||
)
|
||||
.await
|
||||
.unwrap_or_else(|_| {
|
||||
DataUrl::from_slice(
|
||||
"image/png",
|
||||
include_bytes!("../install/package-icon.png"),
|
||||
)
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
let prev_zram = db
|
||||
.mutate(|v| {
|
||||
for (_, pde) in v.as_public_mut().as_package_data_mut().as_entries_mut()? {
|
||||
for (dependency, info) in pde
|
||||
.as_installed_mut()
|
||||
.map(|i| i.as_dependency_info_mut().as_entries_mut())
|
||||
.transpose()?
|
||||
.into_iter()
|
||||
.flatten()
|
||||
{
|
||||
if let Some(url) = url_replacements.get(&dependency) {
|
||||
info.as_icon_mut().ser(url)?;
|
||||
} else {
|
||||
info.as_icon_mut().ser(&DataUrl::from_slice(
|
||||
"image/png",
|
||||
include_bytes!("../install/package-icon.png"),
|
||||
))?;
|
||||
}
|
||||
let manifest = <&mut Value>::from(&mut *info)
|
||||
.as_object_mut()
|
||||
.and_then(|o| o.remove("manifest"));
|
||||
if let Some(title) = manifest
|
||||
.as_ref()
|
||||
.and_then(|m| m.as_object())
|
||||
.and_then(|m| m.get("title"))
|
||||
.and_then(|t| t.as_str())
|
||||
.map(|s| s.to_owned())
|
||||
{
|
||||
info.as_title_mut().ser(&title)?;
|
||||
} else {
|
||||
info.as_title_mut().ser(&dependency.to_string())?;
|
||||
}
|
||||
}
|
||||
}
|
||||
v.as_public_mut()
|
||||
.as_server_info_mut()
|
||||
.as_zram_mut()
|
||||
.replace(&true)
|
||||
})
|
||||
.await?;
|
||||
if !prev_zram {
|
||||
crate::system::enable_zram().await?;
|
||||
}
|
||||
async fn up(&self, _db: &PatchDb) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
async fn down(&self, _db: PatchDb, _secrets: &PgPool) -> Result<(), Error> {
|
||||
async fn down(&self, _db: &PatchDb) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
use async_trait::async_trait;
|
||||
use emver::VersionRange;
|
||||
use sqlx::PgPool;
|
||||
|
||||
use super::v0_3_4::V0_3_0_COMPAT;
|
||||
use super::v0_3_5::V0_3_0_COMPAT;
|
||||
use super::{v0_3_5, VersionT};
|
||||
use crate::prelude::*;
|
||||
|
||||
@@ -11,7 +9,6 @@ const V0_3_5_1: emver::Version = emver::Version::new(0, 3, 5, 1);
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Version;
|
||||
|
||||
#[async_trait]
|
||||
impl VersionT for Version {
|
||||
type Previous = v0_3_5::Version;
|
||||
fn new() -> Self {
|
||||
@@ -23,10 +20,10 @@ impl VersionT for Version {
|
||||
fn compat(&self) -> &'static VersionRange {
|
||||
&V0_3_0_COMPAT
|
||||
}
|
||||
async fn up(&self, _db: PatchDb, _secrets: &PgPool) -> Result<(), Error> {
|
||||
async fn up(&self, _db: &PatchDb) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
async fn down(&self, _db: PatchDb, _secrets: &PgPool) -> Result<(), Error> {
|
||||
async fn down(&self, _db: &PatchDb) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
29
core/startos/src/version/v0_3_6.rs
Normal file
29
core/startos/src/version/v0_3_6.rs
Normal file
@@ -0,0 +1,29 @@
|
||||
use emver::VersionRange;
|
||||
|
||||
use super::v0_3_5::V0_3_0_COMPAT;
|
||||
use super::{v0_3_5_1, VersionT};
|
||||
use crate::prelude::*;
|
||||
|
||||
const V0_3_6: emver::Version = emver::Version::new(0, 3, 6, 0);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Version;
|
||||
|
||||
impl VersionT for Version {
|
||||
type Previous = v0_3_5_1::Version;
|
||||
fn new() -> Self {
|
||||
Version
|
||||
}
|
||||
fn semver(&self) -> emver::Version {
|
||||
V0_3_6
|
||||
}
|
||||
fn compat(&self) -> &'static VersionRange {
|
||||
&V0_3_0_COMPAT
|
||||
}
|
||||
async fn up(&self, _db: &PatchDb) -> Result<(), Error> {
|
||||
Err(Error::new(eyre!("unimplemented"), ErrorKind::Unknown))
|
||||
}
|
||||
async fn down(&self, _db: &PatchDb) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user