mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
Feat/patch migration (#1890)
* feat: Most of the ui conversions and removing the package-recovered * chore: Include the down process. * feat: Add in the potential community packages. * chore: Add in the services * Make it so we skip rebuil. * update version to 033 in FE * chore: Revert to next version for patch-db * fix: Build and check Co-authored-by: Lucy Cifferello <12953208+elvece@users.noreply.github.com>
This commit is contained in:
2
Makefile
2
Makefile
@@ -8,7 +8,7 @@ COMPAT_SRC := $(shell find system-images/compat/ -not -path 'system-images/compa
|
|||||||
UTILS_SRC := $(shell find system-images/utils/ -not -name *.tar)
|
UTILS_SRC := $(shell find system-images/utils/ -not -name *.tar)
|
||||||
BINFMT_SRC := $(shell find system-images/binfmt/ -not -name *.tar)
|
BINFMT_SRC := $(shell find system-images/binfmt/ -not -name *.tar)
|
||||||
BACKEND_SRC := $(shell find backend/src) $(shell find backend/migrations) $(shell find patch-db/*/src) backend/Cargo.toml backend/Cargo.lock
|
BACKEND_SRC := $(shell find backend/src) $(shell find backend/migrations) $(shell find patch-db/*/src) backend/Cargo.toml backend/Cargo.lock
|
||||||
FRONTEND_SHARED_SRC := $(shell find frontend/projects/shared) $(shell ls -p frontend/ | grep -v / | sed 's/^/frontend\//g') frontend/node_modules frontend/config.json patch-db/client/dist frontend/patchdb-ui-seed.json
|
FRONTEND_SHARED_SRC := $(shell find frontend/projects/shared) $(shell ls -p frontend/ | grep -v / | sed 's/^/frontend\//g') frontend/package.json frontend/node_modules frontend/config.json patch-db/client/dist frontend/patchdb-ui-seed.json
|
||||||
FRONTEND_UI_SRC := $(shell find frontend/projects/ui)
|
FRONTEND_UI_SRC := $(shell find frontend/projects/ui)
|
||||||
FRONTEND_SETUP_WIZARD_SRC := $(shell find frontend/projects/setup-wizard)
|
FRONTEND_SETUP_WIZARD_SRC := $(shell find frontend/projects/setup-wizard)
|
||||||
FRONTEND_DIAGNOSTIC_UI_SRC := $(shell find frontend/projects/diagnostic-ui)
|
FRONTEND_DIAGNOSTIC_UI_SRC := $(shell find frontend/projects/diagnostic-ui)
|
||||||
|
|||||||
@@ -28,8 +28,6 @@ pub struct Database {
|
|||||||
pub server_info: ServerInfo,
|
pub server_info: ServerInfo,
|
||||||
#[model]
|
#[model]
|
||||||
pub package_data: AllPackageData,
|
pub package_data: AllPackageData,
|
||||||
#[model]
|
|
||||||
pub recovered_packages: BTreeMap<PackageId, RecoveredPackageInfo>,
|
|
||||||
pub ui: Value,
|
pub ui: Value,
|
||||||
}
|
}
|
||||||
impl Database {
|
impl Database {
|
||||||
@@ -68,7 +66,6 @@ impl Database {
|
|||||||
password_hash,
|
password_hash,
|
||||||
},
|
},
|
||||||
package_data: AllPackageData::default(),
|
package_data: AllPackageData::default(),
|
||||||
recovered_packages: BTreeMap::new(),
|
|
||||||
ui: serde_json::from_str(include_str!("../../../frontend/patchdb-ui-seed.json"))
|
ui: serde_json::from_str(include_str!("../../../frontend/patchdb-ui-seed.json"))
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ use crate::db::model::ServerStatus;
|
|||||||
use crate::install::PKG_DOCKER_DIR;
|
use crate::install::PKG_DOCKER_DIR;
|
||||||
use crate::sound::CIRCLE_OF_5THS_SHORT;
|
use crate::sound::CIRCLE_OF_5THS_SHORT;
|
||||||
use crate::util::Invoke;
|
use crate::util::Invoke;
|
||||||
use crate::version::VersionT;
|
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
|
|
||||||
pub const SYSTEM_REBUILD_PATH: &str = "/media/embassy/config/system-rebuild";
|
pub const SYSTEM_REBUILD_PATH: &str = "/media/embassy/config/system-rebuild";
|
||||||
@@ -225,8 +224,7 @@ pub async fn init(cfg: &RpcContextConfig) -> Result<InitResult, Error> {
|
|||||||
let receipts = InitReceipts::new(&mut handle).await?;
|
let receipts = InitReceipts::new(&mut handle).await?;
|
||||||
|
|
||||||
let should_rebuild = tokio::fs::metadata(SYSTEM_REBUILD_PATH).await.is_ok()
|
let should_rebuild = tokio::fs::metadata(SYSTEM_REBUILD_PATH).await.is_ok()
|
||||||
|| &*receipts.server_version.get(&mut handle).await?
|
|| &*receipts.server_version.get(&mut handle).await? < &emver::Version::new(0, 3, 2, 0);
|
||||||
< &crate::version::Current::new().semver();
|
|
||||||
|
|
||||||
let song = if should_rebuild {
|
let song = if should_rebuild {
|
||||||
Some(NonDetachingJoinHandle::from(tokio::spawn(async {
|
Some(NonDetachingJoinHandle::from(tokio::spawn(async {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use futures::{FutureExt, StreamExt, TryStreamExt};
|
|||||||
use http::header::CONTENT_LENGTH;
|
use http::header::CONTENT_LENGTH;
|
||||||
use http::{Request, Response, StatusCode};
|
use http::{Request, Response, StatusCode};
|
||||||
use hyper::Body;
|
use hyper::Body;
|
||||||
use patch_db::{DbHandle, LockReceipt, LockType};
|
use patch_db::{DbHandle, LockType};
|
||||||
use reqwest::Url;
|
use reqwest::Url;
|
||||||
use rpc_toolkit::command;
|
use rpc_toolkit::command;
|
||||||
use rpc_toolkit::yajrc::RpcError;
|
use rpc_toolkit::yajrc::RpcError;
|
||||||
@@ -30,7 +30,7 @@ use crate::context::{CliContext, RpcContext};
|
|||||||
use crate::core::rpc_continuations::{RequestGuid, RpcContinuation};
|
use crate::core::rpc_continuations::{RequestGuid, RpcContinuation};
|
||||||
use crate::db::model::{
|
use crate::db::model::{
|
||||||
CurrentDependencies, CurrentDependencyInfo, CurrentDependents, InstalledPackageDataEntry,
|
CurrentDependencies, CurrentDependencyInfo, CurrentDependents, InstalledPackageDataEntry,
|
||||||
PackageDataEntry, RecoveredPackageInfo, StaticDependencyInfo, StaticFiles,
|
PackageDataEntry, StaticDependencyInfo, StaticFiles,
|
||||||
};
|
};
|
||||||
use crate::dependencies::{
|
use crate::dependencies::{
|
||||||
add_dependent_to_current_dependents_lists, break_all_dependents_transitive,
|
add_dependent_to_current_dependents_lists, break_all_dependents_transitive,
|
||||||
@@ -667,43 +667,6 @@ pub async fn uninstall_impl(ctx: RpcContext, id: PackageId) -> Result<(), Error>
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[command(
|
|
||||||
rename = "delete-recovered",
|
|
||||||
display(display_none),
|
|
||||||
metadata(sync_db = true)
|
|
||||||
)]
|
|
||||||
pub async fn delete_recovered(
|
|
||||||
#[context] ctx: RpcContext,
|
|
||||||
#[arg] id: PackageId,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
let mut handle = ctx.db.handle();
|
|
||||||
let mut tx = handle.begin().await?;
|
|
||||||
let mut sql_tx = ctx.secret_store.begin().await?;
|
|
||||||
|
|
||||||
let mut recovered_packages = crate::db::DatabaseModel::new()
|
|
||||||
.recovered_packages()
|
|
||||||
.get_mut(&mut tx)
|
|
||||||
.await?;
|
|
||||||
recovered_packages.remove(&id).ok_or_else(|| {
|
|
||||||
Error::new(
|
|
||||||
eyre!("{} not in recovered-packages", id),
|
|
||||||
crate::ErrorKind::NotFound,
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
recovered_packages.save(&mut tx).await?;
|
|
||||||
|
|
||||||
let volumes = ctx.datadir.join(crate::volume::PKG_VOLUME_DIR).join(&id);
|
|
||||||
if tokio::fs::metadata(&volumes).await.is_ok() {
|
|
||||||
tokio::fs::remove_dir_all(&volumes).await?;
|
|
||||||
}
|
|
||||||
cleanup::remove_tor_keys(&mut sql_tx, &id).await?;
|
|
||||||
|
|
||||||
tx.commit().await?;
|
|
||||||
sql_tx.commit().await?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct DownloadInstallReceipts {
|
pub struct DownloadInstallReceipts {
|
||||||
package_receipts: crate::db::package::PackageReceipts,
|
package_receipts: crate::db::package::PackageReceipts,
|
||||||
manifest_receipts: crate::db::package::ManifestReceipts,
|
manifest_receipts: crate::db::package::ManifestReceipts,
|
||||||
@@ -864,8 +827,6 @@ pub async fn download_install_s9pk(
|
|||||||
|
|
||||||
pub struct InstallS9Receipts {
|
pub struct InstallS9Receipts {
|
||||||
config: ConfigReceipts,
|
config: ConfigReceipts,
|
||||||
|
|
||||||
recovered_packages: LockReceipt<BTreeMap<PackageId, RecoveredPackageInfo>, ()>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InstallS9Receipts {
|
impl InstallS9Receipts {
|
||||||
@@ -880,16 +841,9 @@ impl InstallS9Receipts {
|
|||||||
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 config = ConfigReceipts::setup(locks);
|
let config = ConfigReceipts::setup(locks);
|
||||||
|
|
||||||
let recovered_packages = crate::db::DatabaseModel::new()
|
|
||||||
.recovered_packages()
|
|
||||||
.make_locker(LockType::Write)
|
|
||||||
.add_to_keys(locks);
|
|
||||||
|
|
||||||
move |skeleton_key| {
|
move |skeleton_key| {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
config: config(skeleton_key)?,
|
config: config(skeleton_key)?,
|
||||||
recovered_packages: recovered_packages.verify(skeleton_key)?,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1436,38 +1390,6 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin + Send + Sync>(
|
|||||||
&receipts.config.update_dependency_receipts,
|
&receipts.config.update_dependency_receipts,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
} else if let Some(recovered) = {
|
|
||||||
receipts
|
|
||||||
.recovered_packages
|
|
||||||
.get(&mut tx)
|
|
||||||
.await?
|
|
||||||
.remove(pkg_id)
|
|
||||||
} {
|
|
||||||
handle_recovered_package(
|
|
||||||
recovered,
|
|
||||||
manifest,
|
|
||||||
ctx,
|
|
||||||
pkg_id,
|
|
||||||
version,
|
|
||||||
&mut tx,
|
|
||||||
&receipts.config,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
add_dependent_to_current_dependents_lists(
|
|
||||||
&mut tx,
|
|
||||||
pkg_id,
|
|
||||||
¤t_dependencies,
|
|
||||||
&receipts.config.current_dependents,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
update_dependency_errors_of_dependents(
|
|
||||||
ctx,
|
|
||||||
&mut tx,
|
|
||||||
pkg_id,
|
|
||||||
¤t_dependents,
|
|
||||||
&receipts.config.update_dependency_receipts,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
} else {
|
} else {
|
||||||
add_dependent_to_current_dependents_lists(
|
add_dependent_to_current_dependents_lists(
|
||||||
&mut tx,
|
&mut tx,
|
||||||
@@ -1486,16 +1408,6 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin + Send + Sync>(
|
|||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let recovered_packages = {
|
|
||||||
let mut r = receipts.recovered_packages.get(&mut tx).await?;
|
|
||||||
r.remove(pkg_id);
|
|
||||||
r
|
|
||||||
};
|
|
||||||
receipts
|
|
||||||
.recovered_packages
|
|
||||||
.set(&mut tx, recovered_packages)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
if let Some(installed) = pde.installed() {
|
if let Some(installed) = pde.installed() {
|
||||||
reconfigure_dependents_with_live_pointers(ctx, &mut tx, &receipts.config, installed)
|
reconfigure_dependents_with_live_pointers(ctx, &mut tx, &receipts.config, installed)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -1509,46 +1421,6 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin + Send + Sync>(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(ctx, tx, receipts))]
|
|
||||||
async fn handle_recovered_package(
|
|
||||||
recovered: RecoveredPackageInfo,
|
|
||||||
manifest: Manifest,
|
|
||||||
ctx: &RpcContext,
|
|
||||||
pkg_id: &PackageId,
|
|
||||||
version: &Version,
|
|
||||||
tx: &mut patch_db::Transaction<&mut patch_db::PatchDbHandle>,
|
|
||||||
receipts: &ConfigReceipts,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
let configured = if let Some(migration) = manifest.migrations.from(
|
|
||||||
&manifest.containers,
|
|
||||||
ctx,
|
|
||||||
&recovered.version,
|
|
||||||
pkg_id,
|
|
||||||
version,
|
|
||||||
&manifest.volumes,
|
|
||||||
) {
|
|
||||||
migration.await?.configured
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
};
|
|
||||||
if configured && manifest.config.is_some() {
|
|
||||||
crate::config::configure(
|
|
||||||
ctx,
|
|
||||||
tx,
|
|
||||||
pkg_id,
|
|
||||||
None,
|
|
||||||
&None,
|
|
||||||
false,
|
|
||||||
&mut BTreeMap::new(),
|
|
||||||
&mut BTreeMap::new(),
|
|
||||||
&receipts,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument(skip(datadir))]
|
#[instrument(skip(datadir))]
|
||||||
pub fn load_images<'a, P: AsRef<Path> + 'a + Send + Sync>(
|
pub fn load_images<'a, P: AsRef<Path> + 'a + Send + Sync>(
|
||||||
datadir: P,
|
datadir: P,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
pub const DEFAULT_MARKETPLACE: &str = "https://registry.start9.com";
|
pub const DEFAULT_MARKETPLACE: &str = "https://registry.start9.com";
|
||||||
|
pub const COMMUNITY_MARKETPLACE: &str = "https://community-registry.start9.com";
|
||||||
pub const BUFFER_SIZE: usize = 1024;
|
pub const BUFFER_SIZE: usize = 1024;
|
||||||
pub const HOST_IP: [u8; 4] = [172, 18, 0, 1];
|
pub const HOST_IP: [u8; 4] = [172, 18, 0, 1];
|
||||||
pub const TARGET: &str = current_platform::CURRENT_PLATFORM;
|
pub const TARGET: &str = current_platform::CURRENT_PLATFORM;
|
||||||
@@ -97,7 +98,6 @@ pub fn server() -> Result<(), RpcError> {
|
|||||||
install::install,
|
install::install,
|
||||||
install::sideload,
|
install::sideload,
|
||||||
install::uninstall,
|
install::uninstall,
|
||||||
install::delete_recovered,
|
|
||||||
install::list,
|
install::list,
|
||||||
install::update::update,
|
install::update::update,
|
||||||
config::config,
|
config::config,
|
||||||
|
|||||||
@@ -17,8 +17,9 @@ mod v0_3_1_1;
|
|||||||
mod v0_3_1_2;
|
mod v0_3_1_2;
|
||||||
mod v0_3_2;
|
mod v0_3_2;
|
||||||
mod v0_3_2_1;
|
mod v0_3_2_1;
|
||||||
|
mod v0_3_3;
|
||||||
|
|
||||||
pub type Current = v0_3_2_1::Version;
|
pub type Current = v0_3_3::Version;
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
@@ -32,6 +33,7 @@ enum Version {
|
|||||||
V0_3_1_2(Wrapper<v0_3_1_2::Version>),
|
V0_3_1_2(Wrapper<v0_3_1_2::Version>),
|
||||||
V0_3_2(Wrapper<v0_3_2::Version>),
|
V0_3_2(Wrapper<v0_3_2::Version>),
|
||||||
V0_3_2_1(Wrapper<v0_3_2_1::Version>),
|
V0_3_2_1(Wrapper<v0_3_2_1::Version>),
|
||||||
|
V0_3_3(Wrapper<v0_3_3::Version>),
|
||||||
Other(emver::Version),
|
Other(emver::Version),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,6 +58,7 @@ impl Version {
|
|||||||
Version::V0_3_1_2(Wrapper(x)) => x.semver(),
|
Version::V0_3_1_2(Wrapper(x)) => x.semver(),
|
||||||
Version::V0_3_2(Wrapper(x)) => x.semver(),
|
Version::V0_3_2(Wrapper(x)) => x.semver(),
|
||||||
Version::V0_3_2_1(Wrapper(x)) => x.semver(),
|
Version::V0_3_2_1(Wrapper(x)) => x.semver(),
|
||||||
|
Version::V0_3_3(Wrapper(x)) => x.semver(),
|
||||||
Version::Other(x) => x.clone(),
|
Version::Other(x) => x.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -191,6 +194,7 @@ pub async fn init<Db: DbHandle>(
|
|||||||
Version::V0_3_1_2(v) => v.0.migrate_to(&Current::new(), db, receipts).await?,
|
Version::V0_3_1_2(v) => v.0.migrate_to(&Current::new(), db, receipts).await?,
|
||||||
Version::V0_3_2(v) => v.0.migrate_to(&Current::new(), db, receipts).await?,
|
Version::V0_3_2(v) => v.0.migrate_to(&Current::new(), db, receipts).await?,
|
||||||
Version::V0_3_2_1(v) => v.0.migrate_to(&Current::new(), db, receipts).await?,
|
Version::V0_3_2_1(v) => v.0.migrate_to(&Current::new(), db, receipts).await?,
|
||||||
|
Version::V0_3_3(v) => v.0.migrate_to(&Current::new(), db, receipts).await?,
|
||||||
Version::Other(_) => {
|
Version::Other(_) => {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
eyre!("Cannot downgrade"),
|
eyre!("Cannot downgrade"),
|
||||||
@@ -232,6 +236,7 @@ mod tests {
|
|||||||
Just(Version::V0_3_1_2(Wrapper(v0_3_1_2::Version::new()))),
|
Just(Version::V0_3_1_2(Wrapper(v0_3_1_2::Version::new()))),
|
||||||
Just(Version::V0_3_2(Wrapper(v0_3_2::Version::new()))),
|
Just(Version::V0_3_2(Wrapper(v0_3_2::Version::new()))),
|
||||||
Just(Version::V0_3_2_1(Wrapper(v0_3_2_1::Version::new()))),
|
Just(Version::V0_3_2_1(Wrapper(v0_3_2_1::Version::new()))),
|
||||||
|
Just(Version::V0_3_3(Wrapper(v0_3_3::Version::new()))),
|
||||||
em_version().prop_map(Version::Other),
|
em_version().prop_map(Version::Other),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
164
backend/src/version/v0_3_3.rs
Normal file
164
backend/src/version/v0_3_3.rs
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
use async_trait::async_trait;
|
||||||
|
use emver::VersionRange;
|
||||||
|
use serde_json::{json, Value};
|
||||||
|
|
||||||
|
use super::v0_3_0::V0_3_0_COMPAT;
|
||||||
|
use super::*;
|
||||||
|
use crate::{COMMUNITY_MARKETPLACE, DEFAULT_MARKETPLACE};
|
||||||
|
|
||||||
|
const V0_3_3: emver::Version = emver::Version::new(0, 3, 3, 0);
|
||||||
|
|
||||||
|
lazy_static::lazy_static! {
|
||||||
|
static ref COMMUNITY_PACKAGES: Vec<&'static str> = vec![
|
||||||
|
"robosats",
|
||||||
|
"syncthing",
|
||||||
|
"balanceofsatoshis",
|
||||||
|
"lightning-jet",
|
||||||
|
"mastodon",
|
||||||
|
"sphinx-relay",
|
||||||
|
"agora",
|
||||||
|
"lndg",
|
||||||
|
"synapse",
|
||||||
|
"thunderhub",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct Version;
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl VersionT for Version {
|
||||||
|
type Previous = v0_3_2_1::Version;
|
||||||
|
fn new() -> Self {
|
||||||
|
Version
|
||||||
|
}
|
||||||
|
fn semver(&self) -> emver::Version {
|
||||||
|
V0_3_3
|
||||||
|
}
|
||||||
|
fn compat(&self) -> &'static VersionRange {
|
||||||
|
&*V0_3_0_COMPAT
|
||||||
|
}
|
||||||
|
async fn up<Db: DbHandle>(&self, db: &mut Db) -> Result<(), Error> {
|
||||||
|
let mut ui = crate::db::DatabaseModel::new().ui().get_mut(db).await?;
|
||||||
|
|
||||||
|
if let Some(Value::String(selected_url)) =
|
||||||
|
ui["marketplace"]
|
||||||
|
.get("selected-id")
|
||||||
|
.and_then(|selected_id| {
|
||||||
|
if let Value::String(selected_id) = selected_id {
|
||||||
|
return Some(ui["marketplace"]["known-hosts"].get(&selected_id)?);
|
||||||
|
}
|
||||||
|
None
|
||||||
|
})
|
||||||
|
{
|
||||||
|
ui["marketplace"]["selected-url"] = json!(selected_url);
|
||||||
|
}
|
||||||
|
if let Value::Object(ref mut obj) = *ui {
|
||||||
|
obj.remove("pkg-order");
|
||||||
|
obj.remove("auto-check-updates");
|
||||||
|
}
|
||||||
|
let known_hosts = ui["marketplace"]["known-hosts"].take();
|
||||||
|
if let Value::Object(known_hosts) = known_hosts {
|
||||||
|
for (_id, value) in known_hosts {
|
||||||
|
if let (Value::String(name), Value::String(url)) = (&value["name"], &value["url"]) {
|
||||||
|
ui["marketplace"]["known-hosts"][name] = json!(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(Value::Object(ref mut obj)) = ui.get_mut("marketplace") {
|
||||||
|
obj.remove("selected-id");
|
||||||
|
}
|
||||||
|
if ui["marketplace"]["selected-url"].is_null() {
|
||||||
|
ui["marketplace"]["selected-url"] = json!(MarketPlaceUrls::Default.url());
|
||||||
|
}
|
||||||
|
ui.save(db).await?;
|
||||||
|
|
||||||
|
for package_id in crate::db::DatabaseModel::new()
|
||||||
|
.package_data()
|
||||||
|
.keys(db, false)
|
||||||
|
.await?
|
||||||
|
.iter()
|
||||||
|
{
|
||||||
|
let id: &str = &**package_id;
|
||||||
|
if COMMUNITY_PACKAGES.iter().find(|x| x == &&id).is_none() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let mut package = crate::db::DatabaseModel::new()
|
||||||
|
.package_data()
|
||||||
|
.idx_model(package_id)
|
||||||
|
.and_then(|x| x.installed())
|
||||||
|
.get_mut(db)
|
||||||
|
.await?;
|
||||||
|
if let Some(ref mut package) = *package {
|
||||||
|
package.marketplace_url = Some(MarketPlaceUrls::Community.url().parse().unwrap());
|
||||||
|
}
|
||||||
|
package.save(db).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
async fn down<Db: DbHandle>(&self, db: &mut Db) -> Result<(), Error> {
|
||||||
|
let mut ui = crate::db::DatabaseModel::new().ui().get_mut(db).await?;
|
||||||
|
let selected_url = ui["marketplace"]["selected-url"]
|
||||||
|
.as_str()
|
||||||
|
.map(|x| x.to_owned());
|
||||||
|
let known_hosts = ui["marketplace"]["known-hosts"].take();
|
||||||
|
ui["marketplace"]["known-hosts"] = json!({});
|
||||||
|
if let Value::Object(known_hosts) = known_hosts {
|
||||||
|
for (url, name) in known_hosts {
|
||||||
|
if let Value::String(name) = name {
|
||||||
|
let id = uuid::Uuid::new_v4().to_string();
|
||||||
|
if Some(&name) == selected_url.as_ref() {
|
||||||
|
ui["marketplace"]["selected-id"] = Value::String(id.clone());
|
||||||
|
}
|
||||||
|
ui["marketplace"]["known-hosts"][id.as_str()] = json!({
|
||||||
|
"name": name,
|
||||||
|
"url": url
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ui["auto-check-updates"] = Value::Bool(true);
|
||||||
|
ui["pkg-order"] = json!(crate::db::DatabaseModel::new()
|
||||||
|
.package_data()
|
||||||
|
.keys(db, false)
|
||||||
|
.await?
|
||||||
|
.iter()
|
||||||
|
.map(|x| x.to_string())
|
||||||
|
.collect::<Vec<String>>());
|
||||||
|
if let Some(Value::Object(ref mut obj)) = ui.get_mut("marketplace") {
|
||||||
|
obj.remove("selected-url");
|
||||||
|
}
|
||||||
|
ui.save(db).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub enum MarketPlaceUrls {
|
||||||
|
Default,
|
||||||
|
Community,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MarketPlaceUrls {
|
||||||
|
pub fn url(&self) -> String {
|
||||||
|
let url_string = match self {
|
||||||
|
MarketPlaceUrls::Default => DEFAULT_MARKETPLACE,
|
||||||
|
MarketPlaceUrls::Community => COMMUNITY_MARKETPLACE,
|
||||||
|
};
|
||||||
|
format!("{url_string}/")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_that_ui_includes_url() {
|
||||||
|
let ui: Value =
|
||||||
|
serde_json::from_str(include_str!("../../../frontend/patchdb-ui-seed.json")).unwrap();
|
||||||
|
for market_place in [MarketPlaceUrls::Default, MarketPlaceUrls::Community] {
|
||||||
|
let url = market_place.url();
|
||||||
|
assert!(
|
||||||
|
!ui["marketplace"]["known-hosts"][&url].is_null(),
|
||||||
|
"Should have a market place for {url}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
4
frontend/package-lock.json
generated
4
frontend/package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "embassy-os",
|
"name": "embassy-os",
|
||||||
"version": "0.3.2.1",
|
"version": "0.3.3",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "embassy-os",
|
"name": "embassy-os",
|
||||||
"version": "0.3.2.1",
|
"version": "0.3.3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "^14.1.0",
|
"@angular/animations": "^14.1.0",
|
||||||
"@angular/common": "^14.1.0",
|
"@angular/common": "^14.1.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "embassy-os",
|
"name": "embassy-os",
|
||||||
"version": "0.3.2.1",
|
"version": "0.3.3",
|
||||||
"author": "Start9 Labs, Inc",
|
"author": "Start9 Labs, Inc",
|
||||||
"homepage": "https://start9.com/",
|
"homepage": "https://start9.com/",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": null,
|
"name": null,
|
||||||
"ack-welcome": "0.3.2.1",
|
"ack-welcome": "0.3.3",
|
||||||
"marketplace": {
|
"marketplace": {
|
||||||
"selected-url": "https://registry.start9.com/",
|
"selected-url": "https://registry.start9.com/",
|
||||||
"known-hosts": {
|
"known-hosts": {
|
||||||
|
|||||||
@@ -11,11 +11,11 @@
|
|||||||
|
|
||||||
<ion-content class="ion-padding">
|
<ion-content class="ion-padding">
|
||||||
<h2>This release</h2>
|
<h2>This release</h2>
|
||||||
<h4>0.3.2~1</h4>
|
<h4>0.3.3</h4>
|
||||||
<p class="note-padding">
|
<p class="note-padding">
|
||||||
View the complete
|
View the complete
|
||||||
<a
|
<a
|
||||||
href="https://github.com/Start9Labs/embassy-os/releases/tag/v0.3.2.1"
|
href="https://github.com/Start9Labs/embassy-os/releases/tag/v0.3.3"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
noreferrer
|
noreferrer
|
||||||
>release notes</a
|
>release notes</a
|
||||||
@@ -24,30 +24,12 @@
|
|||||||
</p>
|
</p>
|
||||||
<h6>Highlights</h6>
|
<h6>Highlights</h6>
|
||||||
<ul class="spaced-list">
|
<ul class="spaced-list">
|
||||||
<li>Bugfix for LAN URLs</li>
|
<li>Kiosk mode</li>
|
||||||
</ul>
|
<li>x86_64 architecture compatibility</li>
|
||||||
|
<li>Community marketplaces</li>
|
||||||
<br />
|
<li>New update all tab</li>
|
||||||
<h2>Previous releases in this series</h2>
|
<li>Various UI/UX improvements</li>
|
||||||
<h4>0.3.2</h4>
|
<li>Various bugfixes and optimizations</li>
|
||||||
<p class="note-padding">
|
|
||||||
View the complete
|
|
||||||
<a
|
|
||||||
href="https://github.com/Start9Labs/embassy-os/releases/tag/v0.3.2"
|
|
||||||
target="_blank"
|
|
||||||
noreferrer
|
|
||||||
>release notes</a
|
|
||||||
>
|
|
||||||
for more details.
|
|
||||||
</p>
|
|
||||||
<h6>Highlights</h6>
|
|
||||||
<ul class="spaced-list">
|
|
||||||
<li>Autoscrolling for logs</li>
|
|
||||||
<li>Improved connectivity between browser and Embassy</li>
|
|
||||||
<li>Switch to Postgres for EOS database for better performance</li>
|
|
||||||
<li>Multiple bug fixes and under-the-hood improvements</li>
|
|
||||||
<li>Various UI/UX enhancements</li>
|
|
||||||
<li>Removal of product keys</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
<div class="ion-text-center ion-padding">
|
<div class="ion-text-center ion-padding">
|
||||||
<ion-button
|
<ion-button
|
||||||
|
|||||||
@@ -20,9 +20,10 @@ export module Mock {
|
|||||||
updated: true,
|
updated: true,
|
||||||
}
|
}
|
||||||
export const MarketplaceEos: RR.GetMarketplaceEOSRes = {
|
export const MarketplaceEos: RR.GetMarketplaceEOSRes = {
|
||||||
version: '0.3.2.1',
|
version: '0.3.3',
|
||||||
headline: 'Our biggest release ever.',
|
headline: 'Our biggest release ever.',
|
||||||
'release-notes': {
|
'release-notes': {
|
||||||
|
'0.3.3': 'Some **Markdown** release _notes_ for 0.3.3',
|
||||||
'0.3.2.1': 'Some **Markdown** release _notes_ for 0.3.2.1',
|
'0.3.2.1': 'Some **Markdown** release _notes_ for 0.3.2.1',
|
||||||
'0.3.2': 'Some **Markdown** release _notes_ for 0.3.2',
|
'0.3.2': 'Some **Markdown** release _notes_ for 0.3.2',
|
||||||
'0.3.1': 'Some **Markdown** release _notes_ for 0.3.1',
|
'0.3.1': 'Some **Markdown** release _notes_ for 0.3.1',
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export const mockPatchData: DataModel = {
|
|||||||
},
|
},
|
||||||
'server-info': {
|
'server-info': {
|
||||||
id: 'abcdefgh',
|
id: 'abcdefgh',
|
||||||
version: '0.3.2.1',
|
version: '0.3.3',
|
||||||
'last-backup': new Date(new Date().valueOf() - 604800001).toISOString(),
|
'last-backup': new Date(new Date().valueOf() - 604800001).toISOString(),
|
||||||
'lan-address': 'https://embassy-abcdefgh.local',
|
'lan-address': 'https://embassy-abcdefgh.local',
|
||||||
'tor-address': 'http://myveryownspecialtoraddress.onion',
|
'tor-address': 'http://myveryownspecialtoraddress.onion',
|
||||||
|
|||||||
6
package-lock.json
generated
6
package-lock.json
generated
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "embassy-os",
|
|
||||||
"lockfileVersion": 2,
|
|
||||||
"requires": true,
|
|
||||||
"packages": {}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user