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