diff --git a/backend/Cargo.lock b/backend/Cargo.lock index a20c56936..38356b433 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -4760,6 +4760,7 @@ dependencies = [ "trust-dns-server", "typed-builder", "url", + "urlencoding", "uuid", "zeroize", ] @@ -5928,6 +5929,12 @@ dependencies = [ "serde", ] +[[package]] +name = "urlencoding" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9" + [[package]] name = "utf-8" version = "0.7.6" diff --git a/backend/Cargo.toml b/backend/Cargo.toml index 9179f33c3..d4b4e30ad 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -154,6 +154,7 @@ tracing-subscriber = { version = "0.3.14", features = ["env-filter"] } trust-dns-server = "0.22.0" typed-builder = "0.10.0" url = { version = "2.2.2", features = ["serde"] } +urlencoding = "2.1.2" uuid = { version = "1.1.2", features = ["v4"] } zeroize = "1.5.7" diff --git a/backend/src/context/rpc.rs b/backend/src/context/rpc.rs index f3c1e9cf2..8894af0af 100644 --- a/backend/src/context/rpc.rs +++ b/backend/src/context/rpc.rs @@ -11,7 +11,7 @@ use helpers::to_tmp_path; use josekit::jwk::Jwk; use patch_db::json_ptr::JsonPointer; use patch_db::{DbHandle, LockReceipt, LockType, PatchDb}; -use reqwest::Url; +use reqwest::{Client, Proxy, Url}; use rpc_toolkit::Context; use serde::Deserialize; use sqlx::postgres::PgConnectOptions; @@ -34,7 +34,9 @@ use crate::net::wifi::WpaCli; use crate::notifications::NotificationManager; use crate::shutdown::Shutdown; use crate::status::{MainStatus, Status}; +use crate::system::get_mem_info; use crate::util::config::load_config_from_paths; +use crate::util::lshw::{lshw, LshwDevice}; use crate::{Error, ErrorKind, ResultExt}; #[derive(Debug, Default, Deserialize)] @@ -120,6 +122,13 @@ pub struct RpcContextSeed { pub rpc_stream_continuations: Mutex>, pub wifi_manager: Option>>, pub current_secret: Arc, + pub client: Client, + pub hardware: Hardware, +} + +pub struct Hardware { + pub devices: Vec, + pub ram: u64, } pub struct RpcCleanReceipts { @@ -203,6 +212,9 @@ impl RpcContext { let metrics_cache = RwLock::new(None); let notification_manager = NotificationManager::new(secret_store.clone()); tracing::info!("Initialized Notification Manager"); + let tor_proxy_url = format!("socks5h://{tor_proxy}"); + let devices = lshw().await?; + let ram = get_mem_info().await?.total.0 as u64 * 1024 * 1024; let seed = Arc::new(RpcContextSeed { is_closed: AtomicBool::new(false), datadir: base.datadir().to_path_buf(), @@ -235,6 +247,17 @@ impl RpcContext { ) })?, ), + client: Client::builder() + .proxy(Proxy::custom(move |url| { + if url.host_str().map_or(false, |h| h.ends_with(".onion")) { + Some(tor_proxy_url.clone()) + } else { + None + } + })) + .build() + .with_kind(crate::ErrorKind::ParseUrl)?, + hardware: Hardware { devices, ram }, }); let res = Self(seed); diff --git a/backend/src/install/mod.rs b/backend/src/install/mod.rs index e5aaa7ec2..565c0c570 100644 --- a/backend/src/install/mod.rs +++ b/backend/src/install/mod.rs @@ -40,6 +40,7 @@ use crate::dependencies::{ }; use crate::install::cleanup::{cleanup, update_dependency_errors_of_dependents}; use crate::install::progress::{InstallProgress, InstallProgressTracker}; +use crate::marketplace::with_query_params; use crate::notifications::NotificationLevel; use crate::s9pk::manifest::{Manifest, PackageId}; use crate::s9pk::reader::S9pkReader; @@ -136,35 +137,39 @@ pub async fn install( let marketplace_url = marketplace_url.unwrap_or_else(|| crate::DEFAULT_MARKETPLACE.parse().unwrap()); let version_priority = version_priority.unwrap_or_default(); - let man: Manifest = reqwest::get(format!( - "{}/package/v0/manifest/{}?spec={}&version-priority={}&eos-version-compat={}&arch={}", - marketplace_url, - id, - version, - version_priority, - Current::new().compat(), - &*crate::ARCH, - )) - .await - .with_kind(crate::ErrorKind::Registry)? - .error_for_status() - .with_kind(crate::ErrorKind::Registry)? - .json() - .await - .with_kind(crate::ErrorKind::Registry)?; - let s9pk = reqwest::get(format!( - "{}/package/v0/{}.s9pk?spec=={}&version-priority={}&eos-version-compat={}&arch={}", - marketplace_url, - id, - man.version, - version_priority, - Current::new().compat(), - &*crate::ARCH, - )) - .await - .with_kind(crate::ErrorKind::Registry)? - .error_for_status() - .with_kind(crate::ErrorKind::Registry)?; + let man: Manifest = ctx + .client + .get(with_query_params( + &ctx, + format!( + "{}/package/v0/manifest/{}?spec={}&version-priority={}", + marketplace_url, id, version, version_priority, + ) + .parse()?, + )) + .send() + .await + .with_kind(crate::ErrorKind::Registry)? + .error_for_status() + .with_kind(crate::ErrorKind::Registry)? + .json() + .await + .with_kind(crate::ErrorKind::Registry)?; + let s9pk = ctx + .client + .get(with_query_params( + &ctx, + format!( + "{}/package/v0/{}.s9pk?spec=={}&version-priority={}", + marketplace_url, id, man.version, version_priority, + ) + .parse()?, + )) + .send() + .await + .with_kind(crate::ErrorKind::Registry)? + .error_for_status() + .with_kind(crate::ErrorKind::Registry)?; if man.id.as_str() != id || !man.version.satisfies(&version) { return Err(Error::new( @@ -185,16 +190,18 @@ pub async fn install( async { tokio::io::copy( &mut response_to_reader( - reqwest::get(format!( - "{}/package/v0/license/{}?spec=={}&eos-version-compat={}&arch={}", - marketplace_url, - id, - man.version, - Current::new().compat(), - &*crate::ARCH, - )) - .await? - .error_for_status()?, + ctx.client + .get(with_query_params( + &ctx, + format!( + "{}/package/v0/license/{}?spec=={}", + marketplace_url, id, man.version, + ) + .parse()?, + )) + .send() + .await? + .error_for_status()?, ), &mut File::create(public_dir_path.join("LICENSE.md")).await?, ) @@ -204,16 +211,18 @@ pub async fn install( async { tokio::io::copy( &mut response_to_reader( - reqwest::get(format!( - "{}/package/v0/instructions/{}?spec=={}&eos-version-compat={}&arch={}", - marketplace_url, - id, - man.version, - Current::new().compat(), - &*crate::ARCH, - )) - .await? - .error_for_status()?, + ctx.client + .get(with_query_params( + &ctx, + format!( + "{}/package/v0/instructions/{}?spec=={}", + marketplace_url, id, man.version, + ) + .parse()?, + )) + .send() + .await? + .error_for_status()?, ), &mut File::create(public_dir_path.join("INSTRUCTIONS.md")).await?, ) @@ -223,16 +232,18 @@ pub async fn install( async { tokio::io::copy( &mut response_to_reader( - reqwest::get(format!( - "{}/package/v0/icon/{}?spec=={}&eos-version-compat={}&arch={}", - marketplace_url, - id, - man.version, - Current::new().compat(), - &*crate::ARCH, - )) - .await? - .error_for_status()?, + ctx.client + .get(with_query_params( + &ctx, + format!( + "{}/package/v0/icon/{}?spec=={}", + marketplace_url, id, man.version, + ) + .parse()?, + )) + .send() + .await? + .error_for_status()?, ), &mut File::create(public_dir_path.join(format!("icon.{}", icon_type))).await?, ) @@ -928,17 +939,20 @@ pub async fn install_s9pk( { Some(local_man) } else if let Some(marketplace_url) = &marketplace_url { - match reqwest::get(format!( - "{}/package/v0/manifest/{}?spec={}&eos-version-compat={}&arch={}", - marketplace_url, - dep, - info.version, - Current::new().compat(), - &*crate::ARCH, - )) - .await - .with_kind(crate::ErrorKind::Registry)? - .error_for_status() + match ctx + .client + .get(with_query_params( + ctx, + format!( + "{}/package/v0/manifest/{}?spec={}", + marketplace_url, dep, info.version, + ) + .parse()?, + )) + .send() + .await + .with_kind(crate::ErrorKind::Registry)? + .error_for_status() { Ok(a) => Ok(Some( a.json() @@ -963,16 +977,19 @@ pub async fn install_s9pk( let icon_path = dir.join(format!("icon.{}", manifest.assets.icon_type())); if tokio::fs::metadata(&icon_path).await.is_err() { tokio::fs::create_dir_all(&dir).await?; - let icon = reqwest::get(format!( - "{}/package/v0/icon/{}?spec={}&eos-version-compat={}&arch={}", - marketplace_url, - dep, - info.version, - Current::new().compat(), - &*crate::ARCH, - )) - .await - .with_kind(crate::ErrorKind::Registry)?; + let icon = ctx + .client + .get(with_query_params( + ctx, + format!( + "{}/package/v0/icon/{}?spec={}", + marketplace_url, dep, info.version, + ) + .parse()?, + )) + .send() + .await + .with_kind(crate::ErrorKind::Registry)?; let mut dst = File::create(&icon_path).await?; tokio::io::copy(&mut response_to_reader(icon), &mut dst).await?; dst.sync_all().await?; diff --git a/backend/src/marketplace.rs b/backend/src/marketplace.rs index f616174d5..40b81d1cb 100644 --- a/backend/src/marketplace.rs +++ b/backend/src/marketplace.rs @@ -3,6 +3,8 @@ use reqwest::{StatusCode, Url}; use rpc_toolkit::command; use serde_json::Value; +use crate::context::RpcContext; +use crate::version::VersionT; use crate::{Error, ResultExt}; #[command(subcommands(get))] @@ -10,9 +12,34 @@ pub fn marketplace() -> Result<(), Error> { Ok(()) } +pub fn with_query_params(ctx: &RpcContext, mut url: Url) -> Url { + url.query_pairs_mut() + .append_pair( + "os.version", + &crate::version::Current::new().semver().to_string(), + ) + .append_pair( + "os.compat", + &crate::version::Current::new().compat().to_string(), + ) + .append_pair("os.arch", crate::OS_ARCH) + .append_pair("hardware.arch", &*crate::ARCH) + .append_pair("hardware.ram", &ctx.hardware.ram.to_string()); + + for hw in &ctx.hardware.devices { + url.query_pairs_mut() + .append_pair(&format!("hardware.device.{}", hw.class()), hw.product()); + } + + url +} + #[command] -pub async fn get(#[arg] url: Url) -> Result { - let mut response = reqwest::get(url) +pub async fn get(#[context] ctx: RpcContext, #[arg] url: Url) -> Result { + let mut response = ctx + .client + .get(with_query_params(&ctx, url)) + .send() .await .with_kind(crate::ErrorKind::Network)?; let status = response.status(); diff --git a/backend/src/net/static_server.rs b/backend/src/net/static_server.rs index e640d49e9..d191d7724 100644 --- a/backend/src/net/static_server.rs +++ b/backend/src/net/static_server.rs @@ -38,6 +38,8 @@ static NOT_AUTHORIZED: &[u8] = b"Not Authorized"; static EMBEDDED_UIS: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/../frontend/dist/static"); +const PROXY_STRIP_HEADERS: &[&str] = &["cookie", "host", "origin", "referer", "user-agent"]; + fn status_fn(_: i32) -> StatusCode { StatusCode::OK } @@ -236,15 +238,6 @@ pub async fn main_ui_server_router(ctx: RpcContext) -> Result, ui_mode: UiMode) -> Result, Error> { let (request_parts, _body) = req.into_parts(); - let accept_encoding = request_parts - .headers - .get_all(ACCEPT_ENCODING) - .into_iter() - .filter_map(|h| h.to_str().ok()) - .flat_map(|s| s.split(",")) - .filter_map(|s| s.split(";").next()) - .map(|s| s.trim()) - .collect::>(); match &request_parts.method { &Method::GET => { let uri_path = ui_mode.path( @@ -307,6 +300,40 @@ async fn main_embassy_ui(req: Request, ctx: RpcContext) -> Result un_authorized(e, &format!("public/{path}")), } } + (&Method::GET, Some(("proxy", target))) => { + match HasValidSession::from_request_parts(&request_parts, &ctx).await { + Ok(_) => { + let target = urlencoding::decode(target)?; + let res = ctx + .client + .get(target.as_ref()) + .headers( + request_parts + .headers + .iter() + .filter(|(h, _)| { + !PROXY_STRIP_HEADERS + .iter() + .any(|bad| h.as_str().eq_ignore_ascii_case(bad)) + }) + .map(|(h, v)| (h.clone(), v.clone())) + .collect(), + ) + .send() + .await + .with_kind(crate::ErrorKind::Network)?; + let mut hres = Response::builder().status(res.status()); + for (h, v) in res.headers().clone() { + if let Some(h) = h { + hres = hres.header(h, v); + } + } + hres.body(Body::wrap_stream(res.bytes_stream())) + .with_kind(crate::ErrorKind::Network) + } + Err(e) => un_authorized(e, &format!("proxy/{target}")), + } + } (&Method::GET, Some(("eos", "local.crt"))) => { match HasValidSession::from_request_parts(&request_parts, &ctx).await { Ok(_) => cert_send(&ctx.account.read().await.root_ca_cert), @@ -550,8 +577,3 @@ fn e_tag(path: &Path, metadata: Option<&Metadata>) -> String { base32::encode(base32::Alphabet::RFC4648 { padding: false }, res.as_slice()).to_lowercase() ) } - -#[test] -fn test_packed_html() { - assert!(MainUi::get("index.html").is_some()) -} diff --git a/backend/src/s9pk/manifest.rs b/backend/src/s9pk/manifest.rs index 168cdc5dc..52b499375 100644 --- a/backend/src/s9pk/manifest.rs +++ b/backend/src/s9pk/manifest.rs @@ -1,3 +1,4 @@ +use std::collections::BTreeMap; use std::path::{Path, PathBuf}; use color_eyre::eyre::eyre; @@ -16,6 +17,7 @@ use crate::net::interface::Interfaces; use crate::procedure::docker::DockerContainers; use crate::procedure::PackageProcedure; use crate::status::health_check::HealthChecks; +use crate::util::serde::Regex; use crate::util::Version; use crate::version::{Current, VersionT}; use crate::volume::Volumes; @@ -79,6 +81,9 @@ pub struct Manifest { #[serde(default)] pub replaces: Vec, + + #[serde(default)] + pub hardware_requirements: HardwareRequirements, } impl Manifest { @@ -109,6 +114,15 @@ impl Manifest { } } +#[derive(Clone, Debug, Default, Deserialize, Serialize)] +#[serde(rename_all = "kebab-case")] +pub struct HardwareRequirements { + #[serde(default)] + device: BTreeMap, + ram: Option, + arch: Option>, +} + #[derive(Clone, Debug, Default, Deserialize, Serialize)] #[serde(rename_all = "kebab-case")] pub struct Assets { diff --git a/backend/src/system.rs b/backend/src/system.rs index 138e01fea..9e8e0e049 100644 --- a/backend/src/system.rs +++ b/backend/src/system.rs @@ -251,7 +251,7 @@ impl<'de> Deserialize<'de> for Percentage { } #[derive(Clone, Debug)] -pub struct MebiBytes(f64); +pub struct MebiBytes(pub f64); impl Serialize for MebiBytes { fn serialize(&self, serializer: S) -> Result where @@ -310,19 +310,19 @@ pub struct MetricsGeneral { #[derive(Deserialize, Serialize, Clone, Debug)] pub struct MetricsMemory { #[serde(rename = "Percentage Used")] - percentage_used: Percentage, + pub percentage_used: Percentage, #[serde(rename = "Total")] - total: MebiBytes, + pub total: MebiBytes, #[serde(rename = "Available")] - available: MebiBytes, + pub available: MebiBytes, #[serde(rename = "Used")] - used: MebiBytes, + pub used: MebiBytes, #[serde(rename = "Swap Total")] - swap_total: MebiBytes, + pub swap_total: MebiBytes, #[serde(rename = "Swap Free")] - swap_free: MebiBytes, + pub swap_free: MebiBytes, #[serde(rename = "Swap Used")] - swap_used: MebiBytes, + pub swap_used: MebiBytes, } #[derive(Deserialize, Serialize, Clone, Debug)] pub struct MetricsCpu { @@ -698,7 +698,7 @@ pub struct MemInfo { swap_free: Option, } #[instrument(skip_all)] -async fn get_mem_info() -> Result { +pub async fn get_mem_info() -> Result { let contents = tokio::fs::read_to_string("/proc/meminfo").await?; let mut mem_info = MemInfo { mem_total: None, diff --git a/backend/src/update/mod.rs b/backend/src/update/mod.rs index 4618d49d5..90ac2870c 100644 --- a/backend/src/update/mod.rs +++ b/backend/src/update/mod.rs @@ -19,6 +19,7 @@ use crate::db::model::UpdateProgress; use crate::disk::mount::filesystem::bind::Bind; use crate::disk::mount::filesystem::ReadWrite; use crate::disk::mount::guard::MountGuard; +use crate::marketplace::with_query_params; use crate::notifications::NotificationLevel; use crate::sound::{ CIRCLE_OF_5THS_SHORT, UPDATE_FAILED_1, UPDATE_FAILED_2, UPDATE_FAILED_3, UPDATE_FAILED_4, @@ -81,18 +82,19 @@ async fn maybe_do_update( marketplace_url: Url, ) -> Result>, Error> { let mut db = ctx.db.handle(); - let latest_version: Version = reqwest::get(format!( - "{}/eos/v0/latest?eos-version={}&arch={}", - marketplace_url, - Current::new().semver(), - OS_ARCH, - )) - .await - .with_kind(ErrorKind::Network)? - .json::() - .await - .with_kind(ErrorKind::Network)? - .version; + let latest_version: Version = ctx + .client + .get(with_query_params( + &ctx, + format!("{}/eos/v0/latest", marketplace_url,).parse()?, + )) + .send() + .await + .with_kind(ErrorKind::Network)? + .json::() + .await + .with_kind(ErrorKind::Network)? + .version; crate::db::DatabaseModel::new() .server_info() .lock(&mut db, LockType::Write) diff --git a/backend/src/util/lshw.rs b/backend/src/util/lshw.rs new file mode 100644 index 000000000..4de4bf46e --- /dev/null +++ b/backend/src/util/lshw.rs @@ -0,0 +1,49 @@ +use models::{Error, ResultExt}; +use serde::{Deserialize, Serialize}; +use tokio::process::Command; + +use crate::util::Invoke; + +const KNOWN_CLASSES: &[&str] = &["processor", "display"]; + +#[derive(Debug, Deserialize, Serialize)] +#[serde(tag = "class")] +#[serde(rename_all = "kebab-case")] +pub enum LshwDevice { + Processor(LshwProcessor), + Display(LshwDisplay), +} +impl LshwDevice { + pub fn class(&self) -> &'static str { + match self { + Self::Processor(_) => "processor", + Self::Display(_) => "display", + } + } + pub fn product(&self) -> &str { + match self { + Self::Processor(hw) => hw.product.as_str(), + Self::Display(hw) => hw.product.as_str(), + } + } +} + +#[derive(Debug, Deserialize, Serialize)] +pub struct LshwProcessor { + pub product: String, +} + +#[derive(Debug, Deserialize, Serialize)] +pub struct LshwDisplay { + pub product: String, +} + +pub async fn lshw() -> Result, Error> { + let mut cmd = Command::new("lshw"); + cmd.arg("-json"); + for class in KNOWN_CLASSES { + cmd.arg("-class").arg(*class); + } + serde_json::from_slice(&cmd.invoke(crate::ErrorKind::Lshw).await?) + .with_kind(crate::ErrorKind::Deserialization) +} diff --git a/backend/src/util/mod.rs b/backend/src/util/mod.rs index 05435dc5b..dfc1deea2 100644 --- a/backend/src/util/mod.rs +++ b/backend/src/util/mod.rs @@ -27,6 +27,7 @@ pub mod config; pub mod http_reader; pub mod io; pub mod logger; +pub mod lshw; pub mod serde; #[derive(Clone, Copy, Debug)] diff --git a/backend/src/util/serde.rs b/backend/src/util/serde.rs index 75d8cc172..856923c09 100644 --- a/backend/src/util/serde.rs +++ b/backend/src/util/serde.rs @@ -793,3 +793,42 @@ impl> Serialize for Base64 { serializer.serialize_str(&base64::encode(self.0.as_ref())) } } + +#[derive(Clone, Debug)] +pub struct Regex(regex::Regex); +impl From for regex::Regex { + fn from(value: Regex) -> Self { + value.0 + } +} +impl From for Regex { + fn from(value: regex::Regex) -> Self { + Regex(value) + } +} +impl AsRef for Regex { + fn as_ref(&self) -> ®ex::Regex { + &self.0 + } +} +impl AsMut for Regex { + fn as_mut(&mut self) -> &mut regex::Regex { + &mut self.0 + } +} +impl<'de> Deserialize<'de> for Regex { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserialize_from_str(deserializer).map(Self) + } +} +impl Serialize for Regex { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serialize_display(&self.0, serializer) + } +} diff --git a/build/lib/depends b/build/lib/depends index fc35c5335..23d19660e 100644 --- a/build/lib/depends +++ b/build/lib/depends @@ -24,6 +24,7 @@ iw jq libavahi-client3 lm-sensors +lshw lvm2 magic-wormhole man-db diff --git a/build/raspberrypi/make-image.sh b/build/raspberrypi/make-image.sh index 76db9e417..3a0bf5291 100755 --- a/build/raspberrypi/make-image.sh +++ b/build/raspberrypi/make-image.sh @@ -71,6 +71,7 @@ sudo losetup -d $OUTPUT_DEVICE if [ "$ALLOW_VERSION_MISMATCH" != 1 ]; then if [ "$(cat GIT_HASH.txt)" != "$REAL_GIT_HASH" ]; then >&2 echo "startos.raspberrypi.squashfs GIT_HASH.txt mismatch" + >&2 echo "expected $REAL_GIT_HASH (dpkg) found $(cat GIT_HASH.txt) (repo)" exit 1 fi if [ "$(cat VERSION.txt)" != "$REAL_VERSION" ]; then diff --git a/frontend/projects/ui/src/app/services/api/api.types.ts b/frontend/projects/ui/src/app/services/api/api.types.ts index 18f7758af..b1f3db206 100644 --- a/frontend/projects/ui/src/app/services/api/api.types.ts +++ b/frontend/projects/ui/src/app/services/api/api.types.ts @@ -259,19 +259,14 @@ export module RR { // marketplace - export type EnvInfo = { - 'server-id': string - 'eos-version': string - } - export type GetMarketplaceInfoReq = EnvInfo + export type GetMarketplaceInfoReq = { 'server-id': string } export type GetMarketplaceInfoRes = StoreInfo - export type GetMarketplaceEosReq = EnvInfo + export type GetMarketplaceEosReq = { 'server-id': string } export type GetMarketplaceEosRes = MarketplaceEOS export type GetMarketplacePackagesReq = { ids?: { id: string; version: string }[] - 'eos-version-compat': string // iff !ids category?: string query?: string diff --git a/frontend/projects/ui/src/app/services/api/embassy-api.service.ts b/frontend/projects/ui/src/app/services/api/embassy-api.service.ts index 2f6dee4de..168993c11 100644 --- a/frontend/projects/ui/src/app/services/api/embassy-api.service.ts +++ b/frontend/projects/ui/src/app/services/api/embassy-api.service.ts @@ -125,7 +125,6 @@ export abstract class ApiService { path: string, params: Record, url: string, - arch?: string, ): Promise abstract getEos(): Promise diff --git a/frontend/projects/ui/src/app/services/api/embassy-live-api.service.ts b/frontend/projects/ui/src/app/services/api/embassy-live-api.service.ts index 61590fbbd..002baf607 100644 --- a/frontend/projects/ui/src/app/services/api/embassy-live-api.service.ts +++ b/frontend/projects/ui/src/app/services/api/embassy-live-api.service.ts @@ -212,10 +212,7 @@ export class LiveApiService extends ApiService { path: string, qp: Record, baseUrl: string, - arch: string = this.config.packageArch, ): Promise { - // Object.assign(qp, { arch }) - qp['arch'] = arch const fullUrl = `${baseUrl}${path}?${new URLSearchParams(qp).toString()}` return this.rpcRequest({ method: 'marketplace.get', @@ -224,17 +221,13 @@ export class LiveApiService extends ApiService { } async getEos(): Promise { - const { id, version } = await getServerInfo(this.patch) - const qp: RR.GetMarketplaceEosReq = { - 'server-id': id, - 'eos-version': version, - } + const { id } = await getServerInfo(this.patch) + const qp: RR.GetMarketplaceEosReq = { 'server-id': id } return this.marketplaceProxy( '/eos/v0/latest', qp, this.config.marketplace.start9, - this.config.osArch, ) } diff --git a/frontend/projects/ui/src/app/services/api/embassy-mock-api.service.ts b/frontend/projects/ui/src/app/services/api/embassy-mock-api.service.ts index 226a081a2..8a18247a7 100644 --- a/frontend/projects/ui/src/app/services/api/embassy-mock-api.service.ts +++ b/frontend/projects/ui/src/app/services/api/embassy-mock-api.service.ts @@ -352,7 +352,6 @@ export class MockApiService extends ApiService { path: string, params: Record, url: string, - arch = '', ): Promise { await pauseFor(2000) diff --git a/frontend/projects/ui/src/app/services/marketplace.service.ts b/frontend/projects/ui/src/app/services/marketplace.service.ts index f8449d022..47ca8f428 100644 --- a/frontend/projects/ui/src/app/services/marketplace.service.ts +++ b/frontend/projects/ui/src/app/services/marketplace.service.ts @@ -217,10 +217,7 @@ export class MarketplaceService implements AbstractMarketplaceService { return this.patch.watch$('server-info').pipe( take(1), switchMap(serverInfo => { - const qp: RR.GetMarketplaceInfoReq = { - 'server-id': serverInfo.id, - 'eos-version': serverInfo.version, - } + const qp: RR.GetMarketplaceInfoReq = { 'server-id': serverInfo.id } return this.api.marketplaceProxy( '/package/v0/info', qp, @@ -274,28 +271,21 @@ export class MarketplaceService implements AbstractMarketplaceService { private fetchPackages$( url: string, - params: Omit< - RR.GetMarketplacePackagesReq, - 'eos-version-compat' | 'page' | 'per-page' - > = {}, + params: Omit = {}, ): Observable { - return this.patch.watch$('server-info', 'eos-version-compat').pipe( - take(1), - switchMap(versionCompat => { - const qp: RR.GetMarketplacePackagesReq = { - ...params, - 'eos-version-compat': versionCompat, - page: 1, - 'per-page': 100, - } - if (qp.ids) qp.ids = JSON.stringify(qp.ids) + const qp: RR.GetMarketplacePackagesReq = { + ...params, + page: 1, + 'per-page': 100, + } + if (qp.ids) qp.ids = JSON.stringify(qp.ids) - return this.api.marketplaceProxy( - '/package/v0/index', - qp, - url, - ) - }), + return from( + this.api.marketplaceProxy( + '/package/v0/index', + qp, + url, + ), ) } diff --git a/libs/models/src/errors.rs b/libs/models/src/errors.rs index a9f3a943b..c429ccd7c 100644 --- a/libs/models/src/errors.rs +++ b/libs/models/src/errors.rs @@ -76,6 +76,7 @@ pub enum ErrorKind { Systemd = 65, OpenSsh = 66, Zram = 67, + Lshw = 68, } impl ErrorKind { pub fn as_str(&self) -> &'static str { @@ -148,6 +149,7 @@ impl ErrorKind { Systemd => "Systemd Error", OpenSsh => "OpenSSH Error", Zram => "Zram Error", + Lshw => "LSHW Error", } } } diff --git a/system-images/compat/Cargo.lock b/system-images/compat/Cargo.lock index b278458a3..2ab91bf78 100644 --- a/system-images/compat/Cargo.lock +++ b/system-images/compat/Cargo.lock @@ -4296,6 +4296,7 @@ dependencies = [ "trust-dns-server", "typed-builder", "url", + "urlencoding", "uuid 1.2.2", "zeroize", ] @@ -5021,6 +5022,12 @@ dependencies = [ "serde", ] +[[package]] +name = "urlencoding" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9" + [[package]] name = "utf-8" version = "0.7.6"