mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 20:14:49 +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::context::{EitherContext, ExtendedContext};
|
||||||
use crate::db::model::{CurrentDependencyInfo, InstalledPackageDataEntryModel};
|
use crate::db::model::{CurrentDependencyInfo, InstalledPackageDataEntryModel};
|
||||||
use crate::db::util::WithRevision;
|
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::s9pk::manifest::PackageId;
|
||||||
use crate::util::{
|
use crate::util::{
|
||||||
display_none, display_serializable, parse_duration, parse_stdin_deserializable, IoFormat,
|
display_none, display_serializable, parse_duration, parse_stdin_deserializable, IoFormat,
|
||||||
@@ -396,21 +398,7 @@ pub fn configure<'a, Db: DbHandle>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// update dependencies
|
// update dependencies
|
||||||
for (dependency, dep_info) in current_dependencies {
|
update_current_dependents(db, id, ¤t_dependencies).await?;
|
||||||
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?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// cache current config for dependents
|
// cache current config for dependents
|
||||||
overrides.insert(id.clone(), config.clone());
|
overrides.insert(id.clone(), config.clone());
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ pub struct WithDescription<T> {
|
|||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub change_warning: Option<String>,
|
pub warning: Option<String>,
|
||||||
}
|
}
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<T> ValueSpec for WithDescription<T>
|
impl<T> ValueSpec for WithDescription<T>
|
||||||
@@ -318,7 +318,7 @@ pub enum ValueSpecAny {
|
|||||||
Enum(WithDescription<WithDefault<ValueSpecEnum>>),
|
Enum(WithDescription<WithDefault<ValueSpecEnum>>),
|
||||||
List(ValueSpecList),
|
List(ValueSpecList),
|
||||||
Number(WithDescription<WithDefault<WithNullable<ValueSpecNumber>>>),
|
Number(WithDescription<WithDefault<WithNullable<ValueSpecNumber>>>),
|
||||||
Object(WithDescription<WithNullable<ValueSpecObject>>),
|
Object(WithDescription<ValueSpecObject>),
|
||||||
String(WithDescription<WithDefault<WithNullable<ValueSpecString>>>),
|
String(WithDescription<WithDefault<WithNullable<ValueSpecString>>>),
|
||||||
Union(WithDescription<WithDefault<ValueSpecUnion>>),
|
Union(WithDescription<WithDefault<ValueSpecUnion>>),
|
||||||
Pointer(WithDescription<ValueSpecPointer>),
|
Pointer(WithDescription<ValueSpecPointer>),
|
||||||
@@ -947,8 +947,6 @@ impl DefaultableWith for ValueSpecNumber {
|
|||||||
#[serde(rename_all = "kebab-case")]
|
#[serde(rename_all = "kebab-case")]
|
||||||
pub struct ValueSpecObject {
|
pub struct ValueSpecObject {
|
||||||
pub spec: ConfigSpec,
|
pub spec: ConfigSpec,
|
||||||
#[serde(default)]
|
|
||||||
pub null_by_default: bool,
|
|
||||||
pub display_as: Option<String>,
|
pub display_as: Option<String>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub unique_by: UniqueBy,
|
pub unique_by: UniqueBy,
|
||||||
@@ -1016,11 +1014,7 @@ impl DefaultableWith for ValueSpecObject {
|
|||||||
_rng: &mut R,
|
_rng: &mut R,
|
||||||
_timeout: &Option<Duration>,
|
_timeout: &Option<Duration>,
|
||||||
) -> Result<Value, Self::Error> {
|
) -> Result<Value, Self::Error> {
|
||||||
if self.null_by_default {
|
Ok(Value::Object(spec.clone()))
|
||||||
Ok(Value::Null)
|
|
||||||
} else {
|
|
||||||
Ok(Value::Object(spec.clone()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Defaultable for ValueSpecObject {
|
impl Defaultable for ValueSpecObject {
|
||||||
@@ -1031,11 +1025,7 @@ impl Defaultable for ValueSpecObject {
|
|||||||
rng: &mut R,
|
rng: &mut R,
|
||||||
timeout: &Option<Duration>,
|
timeout: &Option<Duration>,
|
||||||
) -> Result<Value, Self::Error> {
|
) -> Result<Value, Self::Error> {
|
||||||
if self.null_by_default {
|
self.spec.gen(rng, timeout).map(Value::Object)
|
||||||
Ok(Value::Null)
|
|
||||||
} else {
|
|
||||||
self.spec.gen(rng, timeout).map(Value::Object)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::action::ActionImplementation;
|
use crate::action::ActionImplementation;
|
||||||
use crate::config::{Config, ConfigSpec};
|
use crate::config::{Config, ConfigSpec};
|
||||||
|
use crate::db::model::CurrentDependencyInfo;
|
||||||
use crate::net::interface::InterfaceId;
|
use crate::net::interface::InterfaceId;
|
||||||
use crate::s9pk::manifest::PackageId;
|
use crate::s9pk::manifest::PackageId;
|
||||||
use crate::status::health_check::{HealthCheckId, HealthCheckResult, HealthCheckResultVariant};
|
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))
|
.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::db::model::InstalledPackageDataEntry;
|
||||||
|
use crate::dependencies::DependencyError;
|
||||||
use crate::s9pk::manifest::{Manifest, PackageId};
|
use crate::s9pk::manifest::{Manifest, PackageId};
|
||||||
|
use crate::util::Version;
|
||||||
use crate::Error;
|
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
|
Ok(()) // TODO
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use std::collections::HashSet;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::io::SeekFrom;
|
use std::io::SeekFrom;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
@@ -32,6 +33,8 @@ use crate::db::model::{
|
|||||||
CurrentDependencyInfo, InstalledPackageDataEntry, PackageDataEntry, StaticDependencyInfo,
|
CurrentDependencyInfo, InstalledPackageDataEntry, PackageDataEntry, StaticDependencyInfo,
|
||||||
StaticFiles,
|
StaticFiles,
|
||||||
};
|
};
|
||||||
|
use crate::dependencies::update_current_dependents;
|
||||||
|
use crate::install::cleanup::update_dependents;
|
||||||
use crate::s9pk::manifest::{Manifest, PackageId};
|
use crate::s9pk::manifest::{Manifest, PackageId};
|
||||||
use crate::s9pk::reader::S9pkReader;
|
use crate::s9pk::reader::S9pkReader;
|
||||||
use crate::status::{DependencyErrors, MainStatus, Status};
|
use crate::status::{DependencyErrors, MainStatus, Status};
|
||||||
@@ -234,8 +237,14 @@ pub async fn download_install_s9pk(
|
|||||||
.await;
|
.await;
|
||||||
|
|
||||||
if let Err(e) = res {
|
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()
|
let mut broken = crate::db::DatabaseModel::new()
|
||||||
.broken_packages()
|
.broken_packages()
|
||||||
.get_mut(&mut handle)
|
.get_mut(&mut handle)
|
||||||
@@ -474,6 +483,31 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin>(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.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 {
|
let installed = InstalledPackageDataEntry {
|
||||||
status: Status {
|
status: Status {
|
||||||
configured: manifest.config.is_none(),
|
configured: manifest.config.is_none(),
|
||||||
@@ -484,30 +518,7 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin>(
|
|||||||
manifest: manifest.clone(),
|
manifest: manifest.clone(),
|
||||||
system_pointers: Vec::new(),
|
system_pointers: Vec::new(),
|
||||||
dependency_info,
|
dependency_info,
|
||||||
current_dependents: {
|
current_dependents: current_dependents.clone(),
|
||||||
// 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_dependencies,
|
current_dependencies,
|
||||||
interface_addresses,
|
interface_addresses,
|
||||||
};
|
};
|
||||||
@@ -521,12 +532,22 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin>(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
pde.save(&mut tx).await?;
|
pde.save(&mut tx).await?;
|
||||||
|
|
||||||
if let PackageDataEntry::Updating {
|
if let PackageDataEntry::Updating {
|
||||||
installed: prev,
|
installed: prev,
|
||||||
manifest: prev_manifest,
|
manifest: prev_manifest,
|
||||||
..
|
..
|
||||||
} = prev
|
} = prev
|
||||||
{
|
{
|
||||||
|
update_dependents(
|
||||||
|
&mut tx,
|
||||||
|
pkg_id,
|
||||||
|
current_dependents
|
||||||
|
.keys()
|
||||||
|
.chain(prev.current_dependents.keys())
|
||||||
|
.collect::<HashSet<_>>(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
let mut configured = prev.status.configured;
|
let mut configured = prev.status.configured;
|
||||||
if let Some(res) = prev_manifest
|
if let Some(res) = prev_manifest
|
||||||
.migrations
|
.migrations
|
||||||
@@ -540,7 +561,7 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin>(
|
|||||||
{
|
{
|
||||||
configured &= res.configured;
|
configured &= res.configured;
|
||||||
}
|
}
|
||||||
cleanup(Ok(prev)).await?;
|
cleanup(&mut tx, Ok(prev)).await?;
|
||||||
if let Some(res) = manifest
|
if let Some(res) = manifest
|
||||||
.migrations
|
.migrations
|
||||||
.from(&prev_manifest.version, pkg_id, version, &manifest.volumes)
|
.from(&prev_manifest.version, pkg_id, version, &manifest.volumes)
|
||||||
@@ -562,6 +583,8 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin>(
|
|||||||
.await?;
|
.await?;
|
||||||
todo!("set as running if viable");
|
todo!("set as running if viable");
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
update_dependents(&mut tx, pkg_id, current_dependents.keys()).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
sql_tx.commit().await?;
|
sql_tx.commit().await?;
|
||||||
|
|||||||
Reference in New Issue
Block a user