miscellaneous bugfixes for alpha12 (#2823)

* miscellaneous bugfixes for alpha12

* fix deserialization of path in cifs share

* catch error in setup.status

* actually reserialize db after migration

* better progress reporting for migrations

* fix infinite drop

* fix raspi build

* fix race condition

* version bump

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
This commit is contained in:
Aiden McClelland
2025-01-28 23:02:52 +00:00
committed by GitHub
parent b83eeeb131
commit 446b37793b
20 changed files with 280 additions and 266 deletions

View File

@@ -12,6 +12,7 @@ use patch_db::json_ptr::ROOT;
use crate::context::RpcContext;
use crate::db::model::Database;
use crate::prelude::*;
use crate::progress::PhaseProgressTrackerHandle;
use crate::Error;
mod v0_3_5;
@@ -31,8 +32,9 @@ mod v0_3_6_alpha_9;
mod v0_3_6_alpha_10;
mod v0_3_6_alpha_11;
mod v0_3_6_alpha_12;
mod v0_3_6_alpha_13;
pub type Current = v0_3_6_alpha_12::Version; // VERSION_BUMP
pub type Current = v0_3_6_alpha_13::Version; // VERSION_BUMP
impl Current {
#[instrument(skip(self, db))]
@@ -55,8 +57,7 @@ impl Current {
let pre_ups = PreUps::load(&from, &self).await?;
db.apply_function(|mut db| {
migrate_from_unchecked(&from, &self, pre_ups, &mut db)?;
from_value::<Database>(db.clone())?;
Ok::<_, Error>((db, ()))
Ok::<_, Error>((to_value(&from_value::<Database>(db.clone())?)?, ()))
})
.await?;
}
@@ -66,31 +67,44 @@ impl Current {
}
}
pub async fn post_init(ctx: &RpcContext) -> Result<(), Error> {
let mut peek;
while let Some(version) = {
peek = ctx.db.peek().await;
peek.as_public()
.as_server_info()
.as_post_init_migration_todos()
.de()?
.first()
.cloned()
.map(Version::from_exver_version)
.as_ref()
.map(Version::as_version_t)
.transpose()?
} {
version.0.post_up(ctx).await?;
ctx.db
.mutate(|db| {
db.as_public_mut()
.as_server_info_mut()
.as_post_init_migration_todos_mut()
.mutate(|m| Ok(m.remove(&version.0.semver())))
})
.await?;
pub async fn post_init(
ctx: &RpcContext,
mut progress: PhaseProgressTrackerHandle,
) -> Result<(), Error> {
let mut peek = ctx.db.peek().await;
let todos = peek
.as_public()
.as_server_info()
.as_post_init_migration_todos()
.de()?;
if !todos.is_empty() {
progress.set_total(todos.len() as u64);
while let Some(version) = {
peek = ctx.db.peek().await;
peek.as_public()
.as_server_info()
.as_post_init_migration_todos()
.de()?
.first()
.cloned()
.map(Version::from_exver_version)
.as_ref()
.map(Version::as_version_t)
.transpose()?
} {
version.0.post_up(ctx).await?;
ctx.db
.mutate(|db| {
db.as_public_mut()
.as_server_info_mut()
.as_post_init_migration_todos_mut()
.mutate(|m| Ok(m.remove(&version.0.semver())))
})
.await?;
progress += 1;
}
}
progress.complete();
Ok(())
}
@@ -115,6 +129,7 @@ enum Version {
V0_3_6_alpha_10(Wrapper<v0_3_6_alpha_10::Version>),
V0_3_6_alpha_11(Wrapper<v0_3_6_alpha_11::Version>),
V0_3_6_alpha_12(Wrapper<v0_3_6_alpha_12::Version>),
V0_3_6_alpha_13(Wrapper<v0_3_6_alpha_13::Version>), // VERSION_BUMP
Other(exver::Version),
}
@@ -151,6 +166,7 @@ impl Version {
Self::V0_3_6_alpha_10(v) => DynVersion(Box::new(v.0)),
Self::V0_3_6_alpha_11(v) => DynVersion(Box::new(v.0)),
Self::V0_3_6_alpha_12(v) => DynVersion(Box::new(v.0)),
Self::V0_3_6_alpha_13(v) => DynVersion(Box::new(v.0)), // VERSION_BUMP
Self::Other(v) => {
return Err(Error::new(
eyre!("unknown version {v}"),
@@ -179,6 +195,7 @@ impl Version {
Version::V0_3_6_alpha_10(Wrapper(x)) => x.semver(),
Version::V0_3_6_alpha_11(Wrapper(x)) => x.semver(),
Version::V0_3_6_alpha_12(Wrapper(x)) => x.semver(),
Version::V0_3_6_alpha_13(Wrapper(x)) => x.semver(), // VERSION_BUMP
Version::Other(x) => x.clone(),
}
}

View File

@@ -193,7 +193,7 @@ pub struct Version;
impl VersionT for Version {
type Previous = v0_3_5_2::Version;
type PreUpRes = (AccountInfo, SshKeys, CifsTargets, Notifications);
type PreUpRes = (AccountInfo, SshKeys, CifsTargets);
fn semver(self) -> exver::Version {
V0_3_6_alpha_0.clone()
}
@@ -208,15 +208,9 @@ impl VersionT for Version {
let cifs = previous_cifs(&pg).await?;
let notifications = previous_notifications(pg).await?;
Ok((account, ssh_keys, cifs, notifications))
Ok((account, ssh_keys, cifs))
}
fn up(
self,
db: &mut Value,
(account, ssh_keys, cifs, notifications): Self::PreUpRes,
) -> Result<(), Error> {
fn up(self, db: &mut Value, (account, ssh_keys, cifs): Self::PreUpRes) -> Result<(), Error> {
let wifi = json!({
"infterface": db["server-info"]["wifi"]["interface"],
"ssids": db["server-info"]["wifi"]["ssids"],
@@ -298,7 +292,7 @@ impl VersionT for Version {
value["sshPubkeys"] = to_value(&ssh_keys)?;
value["availablePorts"] = to_value(&AvailablePorts::new())?;
value["sessions"] = to_value(&Sessions::new())?;
value["notifications"] = to_value(&notifications)?;
value["notifications"] = to_value(&Notifications::new())?;
value["cifs"] = to_value(&cifs)?;
value["packageStores"] = json!({});
value
@@ -375,64 +369,6 @@ impl VersionT for Version {
}
}
async fn previous_notifications(pg: sqlx::Pool<sqlx::Postgres>) -> Result<Notifications, Error> {
let notification_cursor = sqlx::query(r#"SELECT * FROM notifications"#)
.fetch_all(&pg)
.await?;
let notifications = {
let mut notifications = Notifications::default();
for row in notification_cursor {
let package_id = serde_json::from_str::<PackageId>(
row.try_get("package_id")
.with_ctx(|_| (ErrorKind::Database, "package_id"))?,
)
.ok();
let created_at = row
.try_get("created_at")
.with_ctx(|_| (ErrorKind::Database, "created_at"))?;
let code = row
.try_get::<i64, _>("code")
.with_ctx(|_| (ErrorKind::Database, "code"))? as u32;
let id = row
.try_get::<i64, _>("id")
.with_ctx(|_| (ErrorKind::Database, "id"))? as u32;
let level = serde_json::from_str(
row.try_get("level")
.with_ctx(|_| (ErrorKind::Database, "level"))?,
)
.with_kind(ErrorKind::Database)
.with_ctx(|_| (ErrorKind::Database, "level: serde_json "))?;
let title = row
.try_get("title")
.with_ctx(|_| (ErrorKind::Database, "title"))?;
let message = row
.try_get("message")
.with_ctx(|_| (ErrorKind::Database, "message"))?;
let data = serde_json::from_str(
row.try_get("data")
.with_ctx(|_| (ErrorKind::Database, "data"))?,
)
.unwrap_or_default();
notifications.0.insert(
id,
Notification {
package_id,
created_at,
code,
level,
title,
message,
data,
},
);
}
notifications
};
Ok(notifications)
}
#[tracing::instrument(skip_all)]
async fn previous_cifs(pg: &sqlx::Pool<sqlx::Postgres>) -> Result<CifsTargets, Error> {
let cifs = sqlx::query(r#"SELECT * FROM cifs_shares"#)
@@ -440,16 +376,17 @@ async fn previous_cifs(pg: &sqlx::Pool<sqlx::Postgres>) -> Result<CifsTargets, E
.await?
.into_iter()
.map(|row| {
let id: i64 = row.try_get("id")?;
let id: i32 = row.try_get("id")?;
Ok::<_, Error>((
id,
Cifs {
hostname: row
.try_get("hostname")
.with_ctx(|_| (ErrorKind::Database, "hostname"))?,
path: serde_json::from_str(row.try_get("path")?)
.with_kind(ErrorKind::Database)
.with_ctx(|_| (ErrorKind::Database, "path"))?,
path: row
.try_get::<String, _>("path")
.with_ctx(|_| (ErrorKind::Database, "path"))?
.into(),
username: row
.try_get("username")
.with_ctx(|_| (ErrorKind::Database, "username"))?,

View File

@@ -0,0 +1,68 @@
use std::collections::BTreeMap;
use exver::{PreReleaseSegment, VersionRange};
use imbl_value::json;
use super::v0_3_5::V0_3_0_COMPAT;
use super::{v0_3_6_alpha_11, VersionT};
use crate::prelude::*;
lazy_static::lazy_static! {
static ref V0_3_6_alpha_12: exver::Version = exver::Version::new(
[0, 3, 6],
[PreReleaseSegment::String("alpha".into()), 12.into()]
);
}
#[derive(Clone, Copy, Debug, Default)]
pub struct Version;
impl VersionT for Version {
type Previous = v0_3_6_alpha_11::Version;
type PreUpRes = ();
async fn pre_up(self) -> Result<Self::PreUpRes, Error> {
Ok(())
}
fn semver(self) -> exver::Version {
V0_3_6_alpha_12.clone()
}
fn compat(self) -> &'static VersionRange {
&V0_3_0_COMPAT
}
fn up(self, db: &mut Value, _: Self::PreUpRes) -> Result<(), Error> {
let bindings: BTreeMap<u16, Value> = [(
80,
json!({
"enabled": false,
"options": {
"preferredExternalPort": 80,
"addSsl": {
"preferredExternalPort": 443,
"alpn": { "specified": [ "http/1.1", "h2" ] },
},
"secure": null,
},
"net": {
"assignedPort": null,
"assignedSslPort": 443,
"public": false,
}
}),
)]
.into_iter()
.collect();
let onion = db["public"]["serverInfo"]["onionAddress"].clone();
db["public"]["serverInfo"]["host"] = json!({
"bindings": bindings,
"onions": [onion],
"domains": {},
"hostnameInfo": {},
});
Ok(())
}
fn down(self, _db: &mut Value) -> Result<(), Error> {
Ok(())
}
}