mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 12:11:56 +00:00
reorganize package data and write dependencies rpc (#2571)
* wip * finish dependencies * minor fixes
This commit is contained in:
@@ -16,9 +16,8 @@ use crate::action::ActionResult;
|
||||
use crate::config::action::ConfigRes;
|
||||
use crate::context::{CliContext, RpcContext};
|
||||
use crate::core::rpc_continuations::RequestGuid;
|
||||
use crate::db::model::{
|
||||
InstalledPackageInfo, PackageDataEntry, PackageDataEntryInstalled, PackageDataEntryMatchModel,
|
||||
StaticFiles,
|
||||
use crate::db::model::package::{
|
||||
InstalledState, PackageDataEntry, PackageState, PackageStateMatchModelRef, UpdatingState,
|
||||
};
|
||||
use crate::disk::mount::guard::GenericMountGuard;
|
||||
use crate::install::PKG_ARCHIVE_DIR;
|
||||
@@ -28,7 +27,7 @@ use crate::s9pk::S9pk;
|
||||
use crate::service::service_map::InstallProgressHandles;
|
||||
use crate::service::transition::TransitionKind;
|
||||
use crate::status::health_check::HealthCheckResult;
|
||||
use crate::status::{MainStatus, Status};
|
||||
use crate::status::MainStatus;
|
||||
use crate::util::actor::{Actor, BackgroundJobs, SimpleActor};
|
||||
use crate::volume::data_dir;
|
||||
|
||||
@@ -100,7 +99,7 @@ impl Service {
|
||||
) -> Result<Option<Self>, Error> {
|
||||
let handle_installed = {
|
||||
let ctx = ctx.clone();
|
||||
move |s9pk: S9pk, i: Model<InstalledPackageInfo>| async move {
|
||||
move |s9pk: S9pk, i: Model<PackageDataEntry>| async move {
|
||||
for volume_id in &s9pk.as_manifest().volumes {
|
||||
let tmp_path =
|
||||
data_dir(&ctx.datadir, &s9pk.as_manifest().id.clone(), volume_id);
|
||||
@@ -118,16 +117,18 @@ impl Service {
|
||||
};
|
||||
let s9pk_dir = ctx.datadir.join(PKG_ARCHIVE_DIR).join("installed"); // TODO: make this based on hash
|
||||
let s9pk_path = s9pk_dir.join(id).with_extension("s9pk");
|
||||
match ctx
|
||||
let Some(entry) = ctx
|
||||
.db
|
||||
.peek()
|
||||
.await
|
||||
.into_public()
|
||||
.into_package_data()
|
||||
.into_idx(id)
|
||||
.map(|pde| pde.into_match())
|
||||
{
|
||||
Some(PackageDataEntryMatchModel::Installing(_)) => {
|
||||
else {
|
||||
return Ok(None);
|
||||
};
|
||||
match entry.as_state_info().as_match() {
|
||||
PackageStateMatchModelRef::Installing(_) => {
|
||||
if disposition == LoadDisposition::Retry {
|
||||
if let Ok(s9pk) = S9pk::open(s9pk_path, Some(id)).await.map_err(|e| {
|
||||
tracing::error!("Error opening s9pk for install: {e}");
|
||||
@@ -150,14 +151,17 @@ impl Service {
|
||||
.await?;
|
||||
Ok(None)
|
||||
}
|
||||
Some(PackageDataEntryMatchModel::Updating(e)) => {
|
||||
PackageStateMatchModelRef::Updating(s) => {
|
||||
if disposition == LoadDisposition::Retry
|
||||
&& e.as_install_progress().de()?.phases.iter().any(
|
||||
|NamedProgress { name, progress }| {
|
||||
&& s.as_installing_info()
|
||||
.as_progress()
|
||||
.de()?
|
||||
.phases
|
||||
.iter()
|
||||
.any(|NamedProgress { name, progress }| {
|
||||
name.eq_ignore_ascii_case("download")
|
||||
&& progress == &Progress::Complete(true)
|
||||
},
|
||||
)
|
||||
})
|
||||
{
|
||||
if let Ok(s9pk) = S9pk::open(&s9pk_path, Some(id)).await.map_err(|e| {
|
||||
tracing::error!("Error opening s9pk for update: {e}");
|
||||
@@ -166,7 +170,7 @@ impl Service {
|
||||
if let Ok(service) = Self::install(
|
||||
ctx.clone(),
|
||||
s9pk,
|
||||
Some(e.as_installed().as_manifest().as_version().de()?),
|
||||
Some(s.as_manifest().as_version().de()?),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
@@ -181,24 +185,28 @@ impl Service {
|
||||
let s9pk = S9pk::open(s9pk_path, Some(id)).await?;
|
||||
ctx.db
|
||||
.mutate({
|
||||
let manifest = s9pk.as_manifest().clone();
|
||||
|db| {
|
||||
db.as_public_mut()
|
||||
.as_package_data_mut()
|
||||
.as_idx_mut(&manifest.id)
|
||||
.or_not_found(&manifest.id)?
|
||||
.ser(&PackageDataEntry::Installed(PackageDataEntryInstalled {
|
||||
static_files: e.as_static_files().de()?,
|
||||
manifest,
|
||||
installed: e.as_installed().de()?,
|
||||
}))
|
||||
.as_idx_mut(&id)
|
||||
.or_not_found(&id)?
|
||||
.as_state_info_mut()
|
||||
.map_mutate(|s| {
|
||||
if let PackageState::Updating(UpdatingState {
|
||||
manifest, ..
|
||||
}) = s
|
||||
{
|
||||
Ok(PackageState::Installed(InstalledState { manifest }))
|
||||
} else {
|
||||
Err(Error::new(eyre!("Race condition detected - package state changed during load"), ErrorKind::Database))
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
.await?;
|
||||
handle_installed(s9pk, e.as_installed().clone()).await
|
||||
handle_installed(s9pk, entry).await
|
||||
}
|
||||
Some(PackageDataEntryMatchModel::Removing(_))
|
||||
| Some(PackageDataEntryMatchModel::Restoring(_)) => {
|
||||
PackageStateMatchModelRef::Removing(_) | PackageStateMatchModelRef::Restoring(_) => {
|
||||
if let Ok(s9pk) = S9pk::open(s9pk_path, Some(id)).await.map_err(|e| {
|
||||
tracing::error!("Error opening s9pk for removal: {e}");
|
||||
tracing::debug!("{e:?}")
|
||||
@@ -230,18 +238,13 @@ impl Service {
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
Some(PackageDataEntryMatchModel::Installed(i)) => {
|
||||
handle_installed(
|
||||
S9pk::open(s9pk_path, Some(id)).await?,
|
||||
i.as_installed().clone(),
|
||||
)
|
||||
.await
|
||||
PackageStateMatchModelRef::Installed(_) => {
|
||||
handle_installed(S9pk::open(s9pk_path, Some(id)).await?, entry).await
|
||||
}
|
||||
Some(PackageDataEntryMatchModel::Error(e)) => Err(Error::new(
|
||||
PackageStateMatchModelRef::Error(e) => Err(Error::new(
|
||||
eyre!("Failed to parse PackageDataEntry, found {e:?}"),
|
||||
ErrorKind::Deserialization,
|
||||
)),
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,7 +258,6 @@ impl Service {
|
||||
let manifest = s9pk.as_manifest().clone();
|
||||
let developer_key = s9pk.as_archive().signer();
|
||||
let icon = s9pk.icon_data_url().await?;
|
||||
let static_files = StaticFiles::local(&manifest.id, &manifest.version, icon);
|
||||
let service = Self::new(ctx.clone(), s9pk, StartStop::Stop).await?;
|
||||
service
|
||||
.seed
|
||||
@@ -270,32 +272,19 @@ impl Service {
|
||||
}
|
||||
ctx.db
|
||||
.mutate(|d| {
|
||||
d.as_public_mut()
|
||||
let entry = d
|
||||
.as_public_mut()
|
||||
.as_package_data_mut()
|
||||
.as_idx_mut(&manifest.id)
|
||||
.or_not_found(&manifest.id)?
|
||||
.ser(&PackageDataEntry::Installed(PackageDataEntryInstalled {
|
||||
installed: InstalledPackageInfo {
|
||||
current_dependencies: Default::default(), // TODO
|
||||
current_dependents: Default::default(), // TODO
|
||||
dependency_info: Default::default(), // TODO
|
||||
developer_key,
|
||||
status: Status {
|
||||
configured: false, // TODO
|
||||
main: MainStatus::Stopped, // TODO
|
||||
dependency_config_errors: Default::default(), // TODO
|
||||
},
|
||||
interface_addresses: Default::default(), // TODO
|
||||
marketplace_url: None, // TODO
|
||||
manifest: manifest.clone(),
|
||||
last_backup: None, // TODO
|
||||
hosts: Default::default(), // TODO
|
||||
store_exposed_dependents: Default::default(), // TODO
|
||||
store_exposed_ui: Default::default(), // TODO
|
||||
},
|
||||
manifest,
|
||||
static_files,
|
||||
}))
|
||||
.or_not_found(&manifest.id)?;
|
||||
entry
|
||||
.as_state_info_mut()
|
||||
.ser(&PackageState::Installed(InstalledState { manifest }))?;
|
||||
entry.as_developer_key_mut().ser(&developer_key)?;
|
||||
entry.as_icon_mut().ser(&icon)?;
|
||||
// TODO: marketplace url
|
||||
// TODO: dependency info
|
||||
Ok(())
|
||||
})
|
||||
.await?;
|
||||
Ok(service)
|
||||
@@ -466,11 +455,7 @@ impl Actor for ServiceActor {
|
||||
seed.ctx
|
||||
.db
|
||||
.mutate(|d| {
|
||||
if let Some(i) = d
|
||||
.as_public_mut()
|
||||
.as_package_data_mut()
|
||||
.as_idx_mut(&id)
|
||||
.and_then(|p| p.as_installed_mut())
|
||||
if let Some(i) = d.as_public_mut().as_package_data_mut().as_idx_mut(&id)
|
||||
{
|
||||
i.as_status_mut().as_main_mut().ser(&main_status)?;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user