mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-04-04 06:19:44 +00:00
Feature/fe new registry (#2647)
* bugfixes * update fe types * implement new registry types in marketplace and ui * fix marketplace types to have default params * add alt implementation toggle * merge cleanup * more cleanup and notes * fix build * cleanup sync with next/minor * add exver JS parser * parse ValidExVer to string * update types to interface * add VersionRange and comparative functions * Parse ExtendedVersion from string * add conjunction, disjunction, and inversion logic * consider flavor in satisfiedBy fn * consider prerelease for ordering * add compare fn for sorting * rename fns for consistency * refactoring * update compare fn to return null if flavors don't match * begin simplifying dependencies * under construction * wip * add dependency metadata to CurrentDependencyInfo * ditch inheritance for recursive VersionRange constructor. Recursive 'satisfiedBy' fn wip * preprocess manifest * misc fixes * use sdk version as osVersion in manifest * chore: Change the type to just validate and not generate all solutions. * add publishedAt * fix pegjs exports * integrate exver into sdk * misc fixes * complete satisfiedBy fn * refactor - use greaterThanOrEqual and lessThanOrEqual fns * fix tests * update dependency details * update types * remove interim types * rename alt implementation to flavor * cleanup os update * format exver.ts * add s9pk parsing endpoints * fix build * update to exver * exver and bug fixes * update static endpoints + cleanup * cleanup * update static proxy verification * make mocks more robust; fix dep icon fallback; cleanup * refactor alert versions and update fixtures * registry bugfixes * misc fixes * cleanup unused * convert patchdb ui seed to camelCase * update otherVersions type * change otherVersions: null to 'none' * refactor and complete feature * improve static endpoints * fix install params * mask systemd-networkd-wait-online * fix static file fetching * include non-matching versions in otherVersions * convert release notes to modal and clean up displayExver * alert for no other versions * Fix ack-instructions casing * fix indeterminate loader on service install --------- Co-authored-by: Aiden McClelland <me@drbonez.dev> Co-authored-by: Shadowy Super Coder <musashidisciple@proton.me> Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com> Co-authored-by: J H <dragondef@gmail.com> Co-authored-by: Matt Hill <mattnine@protonmail.com>
This commit is contained in:
@@ -1147,18 +1147,14 @@ enum DependencyRequirement {
|
||||
#[ts(type = "string[]")]
|
||||
health_checks: BTreeSet<HealthCheckId>,
|
||||
#[ts(type = "string")]
|
||||
version_spec: VersionRange,
|
||||
#[ts(type = "string")]
|
||||
registry_url: Url,
|
||||
version_range: VersionRange,
|
||||
},
|
||||
#[serde(rename_all = "camelCase")]
|
||||
Exists {
|
||||
#[ts(type = "string")]
|
||||
id: PackageId,
|
||||
#[ts(type = "string")]
|
||||
version_spec: VersionRange,
|
||||
#[ts(type = "string")]
|
||||
registry_url: Url,
|
||||
version_range: VersionRange,
|
||||
},
|
||||
}
|
||||
// filebrowser:exists,bitcoind:running:foo+bar+baz
|
||||
@@ -1168,8 +1164,7 @@ impl FromStr for DependencyRequirement {
|
||||
match s.split_once(':') {
|
||||
Some((id, "e")) | Some((id, "exists")) => Ok(Self::Exists {
|
||||
id: id.parse()?,
|
||||
registry_url: "".parse()?, // TODO
|
||||
version_spec: "*".parse()?, // TODO
|
||||
version_range: "*".parse()?, // TODO
|
||||
}),
|
||||
Some((id, rest)) => {
|
||||
let health_checks = match rest.split_once(':') {
|
||||
@@ -1192,15 +1187,13 @@ impl FromStr for DependencyRequirement {
|
||||
Ok(Self::Running {
|
||||
id: id.parse()?,
|
||||
health_checks,
|
||||
registry_url: "".parse()?, // TODO
|
||||
version_spec: "*".parse()?, // TODO
|
||||
version_range: "*".parse()?, // TODO
|
||||
})
|
||||
}
|
||||
None => Ok(Self::Running {
|
||||
id: s.parse()?,
|
||||
health_checks: BTreeSet::new(),
|
||||
registry_url: "".parse()?, // TODO
|
||||
version_spec: "*".parse()?, // TODO
|
||||
version_range: "*".parse()?, // TODO
|
||||
}),
|
||||
}
|
||||
}
|
||||
@@ -1234,59 +1227,20 @@ async fn set_dependencies(
|
||||
|
||||
let mut deps = BTreeMap::new();
|
||||
for dependency in dependencies {
|
||||
let (dep_id, kind, registry_url, version_spec) = match dependency {
|
||||
DependencyRequirement::Exists {
|
||||
id,
|
||||
registry_url,
|
||||
version_spec,
|
||||
} => (
|
||||
id,
|
||||
CurrentDependencyKind::Exists,
|
||||
registry_url,
|
||||
version_spec,
|
||||
),
|
||||
let (dep_id, kind, version_range) = match dependency {
|
||||
DependencyRequirement::Exists { id, version_range } => {
|
||||
(id, CurrentDependencyKind::Exists, version_range)
|
||||
}
|
||||
DependencyRequirement::Running {
|
||||
id,
|
||||
health_checks,
|
||||
registry_url,
|
||||
version_spec,
|
||||
version_range,
|
||||
} => (
|
||||
id,
|
||||
CurrentDependencyKind::Running { health_checks },
|
||||
registry_url,
|
||||
version_spec,
|
||||
version_range,
|
||||
),
|
||||
};
|
||||
let (icon, title) = match async {
|
||||
let remote_s9pk = S9pk::deserialize(
|
||||
&Arc::new(
|
||||
HttpSource::new(
|
||||
context.seed.ctx.client.clone(),
|
||||
registry_url
|
||||
.join(&format!("package/v2/{}.s9pk?spec={}", dep_id, version_spec))?,
|
||||
)
|
||||
.await?,
|
||||
),
|
||||
None, // TODO
|
||||
)
|
||||
.await?;
|
||||
|
||||
let icon = remote_s9pk.icon_data_url().await?;
|
||||
|
||||
Ok::<_, Error>((icon, remote_s9pk.as_manifest().title.clone()))
|
||||
}
|
||||
.await
|
||||
{
|
||||
Ok(a) => a,
|
||||
Err(e) => {
|
||||
tracing::error!("Error fetching remote s9pk: {e}");
|
||||
tracing::debug!("{e:?}");
|
||||
(
|
||||
DataUrl::from_slice("image/png", include_bytes!("../install/package-icon.png")),
|
||||
dep_id.to_string(),
|
||||
)
|
||||
}
|
||||
};
|
||||
let config_satisfied =
|
||||
if let Some(dep_service) = &*context.seed.ctx.services.get(&dep_id).await {
|
||||
context
|
||||
@@ -1300,17 +1254,25 @@ async fn set_dependencies(
|
||||
} else {
|
||||
true
|
||||
};
|
||||
deps.insert(
|
||||
dep_id,
|
||||
CurrentDependencyInfo {
|
||||
kind,
|
||||
registry_url,
|
||||
version_spec,
|
||||
icon,
|
||||
title,
|
||||
config_satisfied,
|
||||
},
|
||||
);
|
||||
let info = CurrentDependencyInfo {
|
||||
title: context
|
||||
.seed
|
||||
.persistent_container
|
||||
.s9pk
|
||||
.dependency_metadata(&dep_id)
|
||||
.await?
|
||||
.map(|m| m.title),
|
||||
icon: context
|
||||
.seed
|
||||
.persistent_container
|
||||
.s9pk
|
||||
.dependency_icon_data_url(&dep_id)
|
||||
.await?,
|
||||
kind,
|
||||
version_range,
|
||||
config_satisfied,
|
||||
};
|
||||
deps.insert(dep_id, info);
|
||||
}
|
||||
context
|
||||
.seed
|
||||
@@ -1343,23 +1305,19 @@ async fn get_dependencies(context: EffectContext) -> Result<Vec<DependencyRequir
|
||||
.into_iter()
|
||||
.map(|(id, current_dependency_info)| {
|
||||
let CurrentDependencyInfo {
|
||||
registry_url,
|
||||
version_spec,
|
||||
version_range,
|
||||
kind,
|
||||
..
|
||||
} = current_dependency_info;
|
||||
Ok::<_, Error>(match kind {
|
||||
CurrentDependencyKind::Exists => DependencyRequirement::Exists {
|
||||
id,
|
||||
registry_url,
|
||||
version_spec,
|
||||
},
|
||||
CurrentDependencyKind::Exists => {
|
||||
DependencyRequirement::Exists { id, version_range }
|
||||
}
|
||||
CurrentDependencyKind::Running { health_checks } => {
|
||||
DependencyRequirement::Running {
|
||||
id,
|
||||
health_checks,
|
||||
version_spec,
|
||||
registry_url,
|
||||
version_range,
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -1381,7 +1339,8 @@ struct CheckDependenciesResult {
|
||||
package_id: PackageId,
|
||||
is_installed: bool,
|
||||
is_running: bool,
|
||||
health_checks: Vec<HealthCheckResult>,
|
||||
config_satisfied: bool,
|
||||
health_checks: BTreeMap<HealthCheckId, HealthCheckResult>,
|
||||
#[ts(type = "string | null")]
|
||||
version: Option<exver::ExtendedVersion>,
|
||||
}
|
||||
@@ -1415,24 +1374,27 @@ async fn check_dependencies(
|
||||
package_id,
|
||||
is_installed: false,
|
||||
is_running: false,
|
||||
health_checks: vec![],
|
||||
config_satisfied: false,
|
||||
health_checks: Default::default(),
|
||||
version: None,
|
||||
});
|
||||
continue;
|
||||
};
|
||||
let installed_version = package
|
||||
.as_state_info()
|
||||
.as_manifest(ManifestPreference::New)
|
||||
.as_version()
|
||||
.de()?
|
||||
.into_version();
|
||||
let manifest = package.as_state_info().as_manifest(ManifestPreference::New);
|
||||
let installed_version = manifest.as_version().de()?.into_version();
|
||||
let satisfies = manifest.as_satisfies().de()?;
|
||||
let version = Some(installed_version.clone());
|
||||
if !installed_version.satisfies(&dependency_info.version_spec) {
|
||||
if ![installed_version]
|
||||
.into_iter()
|
||||
.chain(satisfies.into_iter().map(|v| v.into_version()))
|
||||
.any(|v| v.satisfies(&dependency_info.version_range))
|
||||
{
|
||||
results.push(CheckDependenciesResult {
|
||||
package_id,
|
||||
is_installed: false,
|
||||
is_running: false,
|
||||
health_checks: vec![],
|
||||
config_satisfied: false,
|
||||
health_checks: Default::default(),
|
||||
version,
|
||||
});
|
||||
continue;
|
||||
@@ -1444,17 +1406,23 @@ async fn check_dependencies(
|
||||
} else {
|
||||
false
|
||||
};
|
||||
let health_checks = status
|
||||
.health()
|
||||
.cloned()
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.map(|(_, val)| val)
|
||||
.collect();
|
||||
let health_checks =
|
||||
if let CurrentDependencyKind::Running { health_checks } = &dependency_info.kind {
|
||||
status
|
||||
.health()
|
||||
.cloned()
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.filter(|(id, _)| health_checks.contains(id))
|
||||
.collect()
|
||||
} else {
|
||||
Default::default()
|
||||
};
|
||||
results.push(CheckDependenciesResult {
|
||||
package_id,
|
||||
is_installed,
|
||||
is_running,
|
||||
config_satisfied: dependency_info.config_satisfied,
|
||||
health_checks,
|
||||
version,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user