mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
chore: Convert the migration to use receipt. (#1842)
This commit is contained in:
@@ -82,8 +82,8 @@ async fn inner_main(cfg_path: Option<&str>) -> Result<Option<Shutdown>, Error> {
|
||||
});
|
||||
|
||||
let mut db = rpc_ctx.db.handle();
|
||||
embassy::hostname::sync_hostname(&mut db).await?;
|
||||
let receipts = embassy::context::rpc::RpcSetNginxReceipts::new(&mut db).await?;
|
||||
embassy::hostname::sync_hostname(&mut db, &receipts.hostname_receipts).await?;
|
||||
|
||||
rpc_ctx.set_nginx_conf(&mut db, receipts).await?;
|
||||
drop(db);
|
||||
|
||||
@@ -23,6 +23,7 @@ use tracing::instrument;
|
||||
|
||||
use crate::core::rpc_continuations::{RequestGuid, RestHandler, RpcContinuation};
|
||||
use crate::db::model::{Database, InstalledPackageDataEntry, PackageDataEntry};
|
||||
use crate::hostname::HostNameReceipt;
|
||||
use crate::init::{init_postgres, pgloader};
|
||||
use crate::install::cleanup::{cleanup_failed, uninstall, CleanupFailedReceipts};
|
||||
use crate::manager::ManagerMap;
|
||||
@@ -175,6 +176,7 @@ impl RpcCleanReceipts {
|
||||
}
|
||||
|
||||
pub struct RpcSetNginxReceipts {
|
||||
pub hostname_receipts: HostNameReceipt,
|
||||
server_info: LockReceipt<crate::db::model::ServerInfo, ()>,
|
||||
}
|
||||
|
||||
@@ -189,12 +191,14 @@ impl RpcSetNginxReceipts {
|
||||
pub fn setup(
|
||||
locks: &mut Vec<patch_db::LockTargetId>,
|
||||
) -> impl FnOnce(&patch_db::Verifier) -> Result<Self, Error> {
|
||||
let hostname_receipts = HostNameReceipt::setup(locks);
|
||||
let server_info = crate::db::DatabaseModel::new()
|
||||
.server_info()
|
||||
.make_locker(LockType::Read)
|
||||
.add_to_keys(locks);
|
||||
move |skeleton_key| {
|
||||
Ok(Self {
|
||||
hostname_receipts: hostname_receipts(skeleton_key)?,
|
||||
server_info: server_info.verify(skeleton_key)?,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -56,36 +56,83 @@ pub async fn set_hostname(hostname: &Hostname) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip(handle))]
|
||||
pub async fn get_id<Db: DbHandle>(handle: &mut Db) -> Result<String, Error> {
|
||||
let id = crate::db::DatabaseModel::new()
|
||||
.server_info()
|
||||
.id()
|
||||
.get(handle, false)
|
||||
.await?;
|
||||
Ok(id.to_string())
|
||||
#[instrument(skip(handle, receipts))]
|
||||
pub async fn get_id<Db: DbHandle>(
|
||||
handle: &mut Db,
|
||||
receipts: &HostNameReceipt,
|
||||
) -> Result<String, Error> {
|
||||
let id = receipts.id.get(handle).await?;
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
pub async fn get_hostname<Db: DbHandle>(handle: &mut Db) -> Result<Hostname, Error> {
|
||||
if let Ok(hostname) = crate::db::DatabaseModel::new()
|
||||
.server_info()
|
||||
.hostname()
|
||||
.get(handle, false)
|
||||
.await
|
||||
{
|
||||
pub async fn get_hostname<Db: DbHandle>(
|
||||
handle: &mut Db,
|
||||
receipts: &HostNameReceipt,
|
||||
) -> Result<Hostname, Error> {
|
||||
if let Ok(hostname) = receipts.hostname.get(handle).await {
|
||||
if let Some(hostname) = hostname.to_owned() {
|
||||
return Ok(Hostname(hostname));
|
||||
}
|
||||
}
|
||||
let id = get_id(handle).await?;
|
||||
let id = get_id(handle, receipts).await?;
|
||||
if id.len() != 8 {
|
||||
return Ok(generate_hostname());
|
||||
}
|
||||
return Ok(Hostname(format!("embassy-{}", id)));
|
||||
}
|
||||
#[instrument(skip(handle))]
|
||||
pub async fn sync_hostname<Db: DbHandle>(handle: &mut Db) -> Result<(), Error> {
|
||||
set_hostname(&get_hostname(handle).await?).await?;
|
||||
|
||||
pub async fn ensure_hostname_is_set<Db: DbHandle>(
|
||||
handle: &mut Db,
|
||||
receipts: &HostNameReceipt,
|
||||
) -> Result<(), Error> {
|
||||
let hostname = get_hostname(handle, &receipts).await?;
|
||||
receipts.hostname.set(handle, Some(hostname.0)).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct HostNameReceipt {
|
||||
hostname: patch_db::LockReceipt<Option<String>, ()>,
|
||||
pub id: patch_db::LockReceipt<String, ()>,
|
||||
}
|
||||
|
||||
impl HostNameReceipt {
|
||||
pub async fn new<'a>(db: &'a mut impl DbHandle) -> Result<Self, Error> {
|
||||
let mut locks = Vec::new();
|
||||
|
||||
let setup = Self::setup(&mut locks);
|
||||
setup(&db.lock_all(locks).await?)
|
||||
}
|
||||
|
||||
pub fn setup(
|
||||
locks: &mut Vec<patch_db::LockTargetId>,
|
||||
) -> impl FnOnce(&patch_db::Verifier) -> Result<Self, Error> {
|
||||
use patch_db::LockType;
|
||||
let hostname = crate::db::DatabaseModel::new()
|
||||
.server_info()
|
||||
.hostname()
|
||||
.make_locker(LockType::Write)
|
||||
.add_to_keys(locks);
|
||||
let id = crate::db::DatabaseModel::new()
|
||||
.server_info()
|
||||
.id()
|
||||
.make_locker(LockType::Write)
|
||||
.add_to_keys(locks);
|
||||
move |skeleton_key| {
|
||||
Ok(Self {
|
||||
hostname: hostname.verify(skeleton_key)?,
|
||||
id: id.verify(skeleton_key)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(handle, receipts))]
|
||||
pub async fn sync_hostname<Db: DbHandle>(
|
||||
handle: &mut Db,
|
||||
receipts: &HostNameReceipt,
|
||||
) -> Result<(), Error> {
|
||||
set_hostname(&get_hostname(handle, receipts).await?).await?;
|
||||
Command::new("systemctl")
|
||||
.arg("restart")
|
||||
.arg("avahi-daemon")
|
||||
|
||||
@@ -66,7 +66,9 @@ impl NetController {
|
||||
None => SslManager::init(db, handle).await,
|
||||
Some(a) => SslManager::import_root_ca(db, a.0, a.1).await,
|
||||
}?;
|
||||
let hostname = get_hostname(handle).await?;
|
||||
|
||||
let hostname_receipts = crate::hostname::HostNameReceipt::new(handle).await?;
|
||||
let hostname = get_hostname(handle, &hostname_receipts).await?;
|
||||
Ok(Self {
|
||||
tor: TorController::init(embassyd_addr, embassyd_tor_key, tor_control).await?,
|
||||
#[cfg(feature = "avahi")]
|
||||
|
||||
@@ -165,7 +165,8 @@ impl SslManager {
|
||||
#[instrument(skip(db, handle))]
|
||||
pub async fn init<Db: DbHandle>(db: PgPool, handle: &mut Db) -> Result<Self, Error> {
|
||||
let store = SslStore::new(db)?;
|
||||
let id = crate::hostname::get_id(handle).await?;
|
||||
let receipts = crate::hostname::HostNameReceipt::new(handle).await?;
|
||||
let id = crate::hostname::get_id(handle, &receipts).await?;
|
||||
let (root_key, root_cert) = match store.load_root_certificate().await? {
|
||||
None => {
|
||||
let root_key = generate_key()?;
|
||||
@@ -528,7 +529,7 @@ fn make_leaf_cert(
|
||||
// let root_cert1 = mgr.root_cert;
|
||||
// let int_key1 = mgr.int_key;
|
||||
// let int_cert1 = mgr.int_cert;
|
||||
//
|
||||
//
|
||||
// assert_eq!(root_cert0.to_pem()?, root_cert1.to_pem()?);
|
||||
// assert_eq!(
|
||||
// int_key0.private_key_to_pem_pkcs8()?,
|
||||
@@ -537,7 +538,7 @@ fn make_leaf_cert(
|
||||
// assert_eq!(int_cert0.to_pem()?, int_cert1.to_pem()?);
|
||||
// Ok(())
|
||||
// }
|
||||
//
|
||||
//
|
||||
// #[tokio::test]
|
||||
// async fn certificate_details_persist() -> Result<(), Error> {
|
||||
// let pool = sqlx::Pool::<sqlx::Postgres>::connect("postgres::memory:").await?;
|
||||
@@ -549,7 +550,7 @@ fn make_leaf_cert(
|
||||
// let package_id = "bitcoind".parse().unwrap();
|
||||
// let (key0, cert_chain0) = mgr.certificate_for("start9", &package_id).await?;
|
||||
// let (key1, cert_chain1) = mgr.certificate_for("start9", &package_id).await?;
|
||||
//
|
||||
//
|
||||
// assert_eq!(
|
||||
// key0.private_key_to_pem_pkcs8()?,
|
||||
// key1.private_key_to_pem_pkcs8()?
|
||||
|
||||
@@ -38,7 +38,7 @@ use crate::disk::mount::filesystem::ReadOnly;
|
||||
use crate::disk::mount::guard::TmpMountGuard;
|
||||
use crate::disk::util::{pvscan, recovery_info, DiskInfo, EmbassyOsRecoveryInfo};
|
||||
use crate::disk::REPAIR_DISK_PATH;
|
||||
use crate::hostname::{get_hostname, Hostname};
|
||||
use crate::hostname::{get_hostname, HostNameReceipt, Hostname};
|
||||
use crate::id::Id;
|
||||
use crate::init::init;
|
||||
use crate::install::PKG_PUBLIC_DIR;
|
||||
@@ -158,7 +158,9 @@ pub async fn attach(
|
||||
|
||||
db_tx.commit().await?;
|
||||
secrets_tx.commit().await?;
|
||||
let hostname = get_hostname(&mut db_handle).await?;
|
||||
|
||||
let hostname_receipts = HostNameReceipt::new(&mut db_handle).await?;
|
||||
let hostname = get_hostname(&mut db_handle, &hostname_receipts).await?;
|
||||
|
||||
let (_, root_ca) = SslManager::init(secrets, &mut db_handle)
|
||||
.await?
|
||||
@@ -321,9 +323,10 @@ pub async fn complete(#[context] ctx: SetupContext) -> Result<SetupResult, Error
|
||||
};
|
||||
let secrets = ctx.secret_store().await?;
|
||||
let mut db = ctx.db(&secrets).await?.handle();
|
||||
let hostname = crate::hostname::get_hostname(&mut db).await?;
|
||||
let receipts = crate::hostname::HostNameReceipt::new(&mut db).await?;
|
||||
let hostname = crate::hostname::get_hostname(&mut db, &receipts).await?;
|
||||
let si = crate::db::DatabaseModel::new().server_info();
|
||||
let id = crate::hostname::get_id(&mut db).await?;
|
||||
let id = crate::hostname::get_id(&mut db, &receipts).await?;
|
||||
si.clone().id().put(&mut db, &id).await?;
|
||||
si.lan_address()
|
||||
.put(&mut db, &hostname.lan_address().parse().unwrap())
|
||||
@@ -378,7 +381,11 @@ pub async fn execute_inner(
|
||||
let db = init(&RpcContextConfig::load(ctx.config_path.as_ref()).await?)
|
||||
.await?
|
||||
.db;
|
||||
let hostname = get_hostname(&mut db.handle()).await?;
|
||||
let hostname = {
|
||||
let mut handle = db.handle();
|
||||
let receipts = crate::hostname::HostNameReceipt::new(&mut handle).await?;
|
||||
get_hostname(&mut handle, &receipts).await?
|
||||
};
|
||||
let res = (hostname.clone(), tor_addr, root_ca.clone());
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = recover_fut
|
||||
@@ -412,15 +419,17 @@ pub async fn execute_inner(
|
||||
let db = init(&RpcContextConfig::load(ctx.config_path.as_ref()).await?)
|
||||
.await?
|
||||
.db;
|
||||
let mut handle = db.handle();
|
||||
let receipts = crate::hostname::HostNameReceipt::new(&mut handle).await?;
|
||||
*ctx.setup_result.write().await = Some((
|
||||
guid,
|
||||
SetupResult {
|
||||
tor_address: format!("http://{}", tor_addr),
|
||||
lan_address: get_hostname(&mut db.handle()).await?.lan_address(),
|
||||
lan_address: get_hostname(&mut handle, &receipts).await?.lan_address(),
|
||||
root_ca: String::from_utf8(root_ca.to_pem()?)?,
|
||||
},
|
||||
));
|
||||
let hostname = get_hostname(&mut db.handle()).await?;
|
||||
let hostname = get_hostname(&mut handle, &receipts).await?;
|
||||
(hostname, tor_addr, root_ca)
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use emver::VersionRange;
|
||||
|
||||
use crate::hostname::{generate_id, get_hostname, sync_hostname};
|
||||
use crate::hostname::{generate_id, sync_hostname};
|
||||
|
||||
use super::v0_3_0::V0_3_0_COMPAT;
|
||||
use super::*;
|
||||
@@ -22,19 +22,11 @@ impl VersionT for Version {
|
||||
&*V0_3_0_COMPAT
|
||||
}
|
||||
async fn up<Db: DbHandle>(&self, db: &mut Db) -> Result<(), Error> {
|
||||
let hostname = get_hostname(db).await?;
|
||||
crate::db::DatabaseModel::new()
|
||||
.server_info()
|
||||
.hostname()
|
||||
.put(db, &Some(hostname.0))
|
||||
.await?;
|
||||
crate::db::DatabaseModel::new()
|
||||
.server_info()
|
||||
.id()
|
||||
.put(db, &generate_id())
|
||||
.await?;
|
||||
let receipts = crate::hostname::HostNameReceipt::new(db).await?;
|
||||
crate::hostname::ensure_hostname_is_set(db, &receipts).await?;
|
||||
receipts.id.set(db, generate_id()).await?;
|
||||
|
||||
sync_hostname(db).await?;
|
||||
sync_hostname(db, &receipts).await?;
|
||||
Ok(())
|
||||
}
|
||||
async fn down<Db: DbHandle>(&self, _db: &mut Db) -> Result<(), Error> {
|
||||
|
||||
Reference in New Issue
Block a user