mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 10:21:52 +00:00
config changes; cleanup wip
This commit is contained in:
committed by
Aiden McClelland
parent
6c7dc71ed4
commit
0aa75ee008
@@ -17,7 +17,9 @@ use crate::config::spec::PackagePointerSpecVariant;
|
||||
use crate::context::{EitherContext, ExtendedContext};
|
||||
use crate::db::model::{CurrentDependencyInfo, InstalledPackageDataEntryModel};
|
||||
use crate::db::util::WithRevision;
|
||||
use crate::dependencies::{BreakageRes, DependencyError, TaggedDependencyError};
|
||||
use crate::dependencies::{
|
||||
update_current_dependents, BreakageRes, DependencyError, TaggedDependencyError,
|
||||
};
|
||||
use crate::s9pk::manifest::PackageId;
|
||||
use crate::util::{
|
||||
display_none, display_serializable, parse_duration, parse_stdin_deserializable, IoFormat,
|
||||
@@ -396,21 +398,7 @@ pub fn configure<'a, Db: DbHandle>(
|
||||
};
|
||||
|
||||
// update dependencies
|
||||
for (dependency, dep_info) in current_dependencies {
|
||||
if let Some(dependency_model) = crate::db::DatabaseModel::new()
|
||||
.package_data()
|
||||
.idx_model(&dependency)
|
||||
.and_then(|pkg| pkg.installed())
|
||||
.check(db)
|
||||
.await?
|
||||
{
|
||||
dependency_model
|
||||
.current_dependents()
|
||||
.idx_model(id)
|
||||
.put(db, &dep_info)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
update_current_dependents(db, id, ¤t_dependencies).await?;
|
||||
|
||||
// cache current config for dependents
|
||||
overrides.insert(id.clone(), config.clone());
|
||||
|
||||
@@ -245,7 +245,7 @@ pub struct WithDescription<T> {
|
||||
pub description: Option<String>,
|
||||
pub name: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub change_warning: Option<String>,
|
||||
pub warning: Option<String>,
|
||||
}
|
||||
#[async_trait]
|
||||
impl<T> ValueSpec for WithDescription<T>
|
||||
@@ -318,7 +318,7 @@ pub enum ValueSpecAny {
|
||||
Enum(WithDescription<WithDefault<ValueSpecEnum>>),
|
||||
List(ValueSpecList),
|
||||
Number(WithDescription<WithDefault<WithNullable<ValueSpecNumber>>>),
|
||||
Object(WithDescription<WithNullable<ValueSpecObject>>),
|
||||
Object(WithDescription<ValueSpecObject>),
|
||||
String(WithDescription<WithDefault<WithNullable<ValueSpecString>>>),
|
||||
Union(WithDescription<WithDefault<ValueSpecUnion>>),
|
||||
Pointer(WithDescription<ValueSpecPointer>),
|
||||
@@ -947,8 +947,6 @@ impl DefaultableWith for ValueSpecNumber {
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct ValueSpecObject {
|
||||
pub spec: ConfigSpec,
|
||||
#[serde(default)]
|
||||
pub null_by_default: bool,
|
||||
pub display_as: Option<String>,
|
||||
#[serde(default)]
|
||||
pub unique_by: UniqueBy,
|
||||
@@ -1016,11 +1014,7 @@ impl DefaultableWith for ValueSpecObject {
|
||||
_rng: &mut R,
|
||||
_timeout: &Option<Duration>,
|
||||
) -> Result<Value, Self::Error> {
|
||||
if self.null_by_default {
|
||||
Ok(Value::Null)
|
||||
} else {
|
||||
Ok(Value::Object(spec.clone()))
|
||||
}
|
||||
Ok(Value::Object(spec.clone()))
|
||||
}
|
||||
}
|
||||
impl Defaultable for ValueSpecObject {
|
||||
@@ -1031,11 +1025,7 @@ impl Defaultable for ValueSpecObject {
|
||||
rng: &mut R,
|
||||
timeout: &Option<Duration>,
|
||||
) -> Result<Value, Self::Error> {
|
||||
if self.null_by_default {
|
||||
Ok(Value::Null)
|
||||
} else {
|
||||
self.spec.gen(rng, timeout).map(Value::Object)
|
||||
}
|
||||
self.spec.gen(rng, timeout).map(Value::Object)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::action::ActionImplementation;
|
||||
use crate::config::{Config, ConfigSpec};
|
||||
use crate::db::model::CurrentDependencyInfo;
|
||||
use crate::net::interface::InterfaceId;
|
||||
use crate::s9pk::manifest::PackageId;
|
||||
use crate::status::health_check::{HealthCheckId, HealthCheckResult, HealthCheckResultVariant};
|
||||
@@ -254,3 +255,26 @@ impl DependencyConfig {
|
||||
.map_err(|e| Error::new(anyhow!("{}", e.1), crate::ErrorKind::AutoConfigure))
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn update_current_dependents<Db: DbHandle>(
|
||||
db: &mut Db,
|
||||
dependent_id: &PackageId,
|
||||
current_dependencies: &IndexMap<PackageId, CurrentDependencyInfo>,
|
||||
) -> Result<(), Error> {
|
||||
for (dependency, dep_info) in current_dependencies {
|
||||
if let Some(dependency_model) = crate::db::DatabaseModel::new()
|
||||
.package_data()
|
||||
.idx_model(&dependency)
|
||||
.and_then(|pkg| pkg.installed())
|
||||
.check(db)
|
||||
.await?
|
||||
{
|
||||
dependency_model
|
||||
.current_dependents()
|
||||
.idx_model(dependent_id)
|
||||
.put(db, &dep_info)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,7 +1,73 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use patch_db::DbHandle;
|
||||
|
||||
use crate::db::model::InstalledPackageDataEntry;
|
||||
use crate::dependencies::DependencyError;
|
||||
use crate::s9pk::manifest::{Manifest, PackageId};
|
||||
use crate::util::Version;
|
||||
use crate::Error;
|
||||
|
||||
pub async fn cleanup(info: Result<InstalledPackageDataEntry, &Manifest>) -> Result<(), Error> {
|
||||
pub async fn update_dependents<'a, Db: DbHandle, I: IntoIterator<Item = &'a PackageId>>(
|
||||
db: &mut Db,
|
||||
id: &PackageId,
|
||||
deps: I,
|
||||
) -> Result<(), Error> {
|
||||
for dep in deps {
|
||||
let man = crate::db::DatabaseModel::new()
|
||||
.package_data()
|
||||
.idx_model(&dep)
|
||||
.expect(db)
|
||||
.await?
|
||||
.installed()
|
||||
.expect(db)
|
||||
.await?
|
||||
.manifest()
|
||||
.get(db, true)
|
||||
.await?;
|
||||
if let Err(e) = man
|
||||
.dependencies
|
||||
.0
|
||||
.get(id)
|
||||
.ok_or_else(|| {
|
||||
Error::new(
|
||||
anyhow!("missing dependency info"),
|
||||
crate::ErrorKind::Database,
|
||||
)
|
||||
})?
|
||||
.satisfied(db, id, None, dep, &man.version, &man.volumes)
|
||||
.await?
|
||||
{
|
||||
let mut errs = crate::db::DatabaseModel::new()
|
||||
.package_data()
|
||||
.idx_model(&dep)
|
||||
.expect(db)
|
||||
.await?
|
||||
.installed()
|
||||
.expect(db)
|
||||
.await?
|
||||
.status()
|
||||
.dependency_errors()
|
||||
.get_mut(db)
|
||||
.await?;
|
||||
errs.0.insert(id.clone(), e);
|
||||
errs.save(db).await?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn cleanup<Db: DbHandle>(
|
||||
db: &mut Db,
|
||||
info: Result<InstalledPackageDataEntry, &Manifest>,
|
||||
) -> Result<(), Error> {
|
||||
let man = match info {
|
||||
Ok(pde) => {
|
||||
todo!();
|
||||
Cow::Owned(pde.manifest)
|
||||
}
|
||||
Err(man) => Cow::Borrowed(man),
|
||||
};
|
||||
Ok(()) // TODO
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::Display;
|
||||
use std::io::SeekFrom;
|
||||
use std::path::Path;
|
||||
@@ -32,6 +33,8 @@ use crate::db::model::{
|
||||
CurrentDependencyInfo, InstalledPackageDataEntry, PackageDataEntry, StaticDependencyInfo,
|
||||
StaticFiles,
|
||||
};
|
||||
use crate::dependencies::update_current_dependents;
|
||||
use crate::install::cleanup::update_dependents;
|
||||
use crate::s9pk::manifest::{Manifest, PackageId};
|
||||
use crate::s9pk::reader::S9pkReader;
|
||||
use crate::status::{DependencyErrors, MainStatus, Status};
|
||||
@@ -234,8 +237,14 @@ pub async fn download_install_s9pk(
|
||||
.await;
|
||||
|
||||
if let Err(e) = res {
|
||||
if let Err(e) = cleanup(Err(temp_manifest)).await {
|
||||
let mut handle = ctx.db.handle();
|
||||
let mut handle = ctx.db.handle();
|
||||
if let Err(e) = cleanup(&mut handle, Err(temp_manifest)).await {
|
||||
log::error!(
|
||||
"Failed to clean up {}@{}: {}: Adding to broken packages",
|
||||
pkg_id,
|
||||
version,
|
||||
e
|
||||
);
|
||||
let mut broken = crate::db::DatabaseModel::new()
|
||||
.broken_packages()
|
||||
.get_mut(&mut handle)
|
||||
@@ -474,6 +483,31 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin>(
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
update_current_dependents(&mut tx, pkg_id, ¤t_dependencies).await?;
|
||||
let current_dependents = {
|
||||
// search required dependencies
|
||||
let mut deps = IndexMap::new();
|
||||
for package in crate::db::DatabaseModel::new()
|
||||
.package_data()
|
||||
.keys(&mut tx, true)
|
||||
.await?
|
||||
{
|
||||
if let Some(dep) = crate::db::DatabaseModel::new()
|
||||
.package_data()
|
||||
.idx_model(&package)
|
||||
.expect(&mut tx)
|
||||
.await?
|
||||
.installed()
|
||||
.and_then(|i| i.current_dependencies().idx_model(pkg_id))
|
||||
.get(&mut tx, true)
|
||||
.await?
|
||||
.to_owned()
|
||||
{
|
||||
deps.insert(package, dep);
|
||||
}
|
||||
}
|
||||
deps
|
||||
};
|
||||
let installed = InstalledPackageDataEntry {
|
||||
status: Status {
|
||||
configured: manifest.config.is_none(),
|
||||
@@ -484,30 +518,7 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin>(
|
||||
manifest: manifest.clone(),
|
||||
system_pointers: Vec::new(),
|
||||
dependency_info,
|
||||
current_dependents: {
|
||||
// search required dependencies
|
||||
let mut deps = IndexMap::new();
|
||||
for package in crate::db::DatabaseModel::new()
|
||||
.package_data()
|
||||
.keys(&mut tx, true)
|
||||
.await?
|
||||
{
|
||||
if let Some(dep) = crate::db::DatabaseModel::new()
|
||||
.package_data()
|
||||
.idx_model(&package)
|
||||
.expect(&mut tx)
|
||||
.await?
|
||||
.installed()
|
||||
.and_then(|i| i.current_dependencies().idx_model(pkg_id))
|
||||
.get(&mut tx, true)
|
||||
.await?
|
||||
.to_owned()
|
||||
{
|
||||
deps.insert(package, dep);
|
||||
}
|
||||
}
|
||||
deps
|
||||
},
|
||||
current_dependents: current_dependents.clone(),
|
||||
current_dependencies,
|
||||
interface_addresses,
|
||||
};
|
||||
@@ -521,12 +532,22 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin>(
|
||||
},
|
||||
);
|
||||
pde.save(&mut tx).await?;
|
||||
|
||||
if let PackageDataEntry::Updating {
|
||||
installed: prev,
|
||||
manifest: prev_manifest,
|
||||
..
|
||||
} = prev
|
||||
{
|
||||
update_dependents(
|
||||
&mut tx,
|
||||
pkg_id,
|
||||
current_dependents
|
||||
.keys()
|
||||
.chain(prev.current_dependents.keys())
|
||||
.collect::<HashSet<_>>(),
|
||||
)
|
||||
.await?;
|
||||
let mut configured = prev.status.configured;
|
||||
if let Some(res) = prev_manifest
|
||||
.migrations
|
||||
@@ -540,7 +561,7 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin>(
|
||||
{
|
||||
configured &= res.configured;
|
||||
}
|
||||
cleanup(Ok(prev)).await?;
|
||||
cleanup(&mut tx, Ok(prev)).await?;
|
||||
if let Some(res) = manifest
|
||||
.migrations
|
||||
.from(&prev_manifest.version, pkg_id, version, &manifest.volumes)
|
||||
@@ -562,6 +583,8 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin>(
|
||||
.await?;
|
||||
todo!("set as running if viable");
|
||||
}
|
||||
} else {
|
||||
update_dependents(&mut tx, pkg_id, current_dependents.keys()).await?;
|
||||
}
|
||||
|
||||
sql_tx.commit().await?;
|
||||
|
||||
Reference in New Issue
Block a user