From 2b1876e01a81b84d1edfc43ad9cf481f1039a9a9 Mon Sep 17 00:00:00 2001 From: tiziodcaio Date: Mon, 2 Oct 2023 12:12:37 +0200 Subject: [PATCH 01/10] Add link flag BROKEN - I need help for fixing the connector in the GUI. The TUI works well. --- extension/src/sites/manage.js | 9 ++++ native/src/components/runtime.rs | 87 +++++++++++++++++++++++++++++++- native/src/connector/process.rs | 5 +- native/src/connector/request.rs | 9 +++- native/src/console/app.rs | 7 ++- native/src/console/runtime.rs | 11 +++- native/src/storage.rs | 5 ++ 7 files changed, 126 insertions(+), 7 deletions(-) diff --git a/extension/src/sites/manage.js b/extension/src/sites/manage.js index 70760a7f..d831d8cc 100644 --- a/extension/src/sites/manage.js +++ b/extension/src/sites/manage.js @@ -865,6 +865,12 @@ async function handleSettings (hasChanged = false) { this.disabled = true this.innerText = await getMessage('buttonReinstallProcessing') + // Listen for use Linked runtime + document.getElementById('settings-use-linked-runtime').addEventListener('change', async function () { + config.use_linked_runtime = this.checked + await setConfig(config) + }) + const responseUninstall = await browser.runtime.sendNativeMessage('firefoxpwa', { cmd: 'UninstallRuntime' }) if (responseUninstall.type === 'Error') throw new Error(responseUninstall.data) if (responseUninstall.type !== 'RuntimeUninstalled') throw new Error(`Received invalid response type: ${responseUninstall.type}`) @@ -913,6 +919,7 @@ async function handleSettings (hasChanged = false) { document.getElementById('settings-enable-wayland-container').classList.remove('d-none') document.getElementById('settings-use-xinput2-container').classList.remove('d-none') document.getElementById('settings-use-portals-container').classList.remove('d-none') + document.getElementById('settings-use-linked-runtime-container').classList.remove('d-none') } // Hide patching setting on macOS @@ -927,6 +934,7 @@ async function handleSettings (hasChanged = false) { document.getElementById('settings-enable-wayland').checked = config.runtime_enable_wayland document.getElementById('settings-use-xinput2').checked = config.runtime_use_xinput2 document.getElementById('settings-use-portals').checked = config.runtime_use_portals + document.getElementById('settings-use-linked-runtime').checked = config.use_linked_runtime document.getElementById('settings-always-patch').checked = config.always_patch // Enable settings inputs @@ -937,6 +945,7 @@ async function handleSettings (hasChanged = false) { document.getElementById('settings-enable-wayland').disabled = false document.getElementById('settings-use-xinput2').disabled = false document.getElementById('settings-use-portals').disabled = false + document.getElementById('settings-use-linked-runtime').disabled = false document.getElementById('settings-always-patch').disabled = false // Helper function to update config diff --git a/native/src/components/runtime.rs b/native/src/components/runtime.rs index f6f37541..32cd1fc4 100644 --- a/native/src/components/runtime.rs +++ b/native/src/components/runtime.rs @@ -195,6 +195,21 @@ impl Runtime { const COPY_ERROR: &str = "Failed to copy the runtime"; const CLEANUP_ERROR: &str = "Failed to clean up the runtime"; + #[cfg(target_os = "linux")] + { + use crate::storage::Storage; + + let dirs = ProjectDirs::new()?; + let mut storage = Storage::load(&dirs)?; + + if storage.config.use_linked_runtime { + self.uninstall()?; + } + + storage.config.use_linked_runtime = false; + storage.write(&dirs)?; + } + warn!("This will download the unmodified Mozilla Firefox and locally modify it"); warn!("Firefox is licensed under the Mozilla Public License 2.0"); warn!("Firefox is a trademark of the Mozilla Foundation in the U.S. and other countries"); @@ -267,13 +282,81 @@ impl Runtime { remove_dir_all(extracted).context(CLEANUP_ERROR)?; info!("Runtime installed!"); + + Ok(()) + } + + #[cfg(target_os = "linux")] + pub fn link(&self) -> Result<()> { + use std::fs::{copy, create_dir_all}; + use std::os::unix::fs::symlink; + + use crate::storage::Storage; + + let dirs = ProjectDirs::new()?; + let mut storage = Storage::load(&dirs)?; + + if !storage.config.use_linked_runtime { + self.uninstall()?; + } + + storage.config.use_linked_runtime = true; + storage.write(&dirs)?; + + info!("Linking the runtime"); + + if Path::new("/usr/lib/firefox/").exists() { + for entry in read_dir("/usr/lib/firefox/")?.flatten() { + let entry = entry.path(); + match entry.file_name().expect("Couldn't retrieve a file name").to_str() { + Some("browser") => { + create_dir_all(self.directory.join("browser"))?; + symlink(entry.join("chrome"), self.directory.join("browser/chrome"))?; + symlink( + entry.join("crashreporter-override.ini"), + self.directory.join("browser/crashreporter-override.ini"), + )?; + symlink(entry.join("features"), self.directory.join("browser/features"))?; + symlink(entry.join("omni.ja"), self.directory.join("browser/omni.ja"))?; + } + Some("defaults") => { + create_dir_all(self.directory.join("defaults/pref"))?; + symlink( + entry.join("defaults/pref/channel-prefs.js"), + self.directory.join("defaults/pref/channel-prefs.js"), + )?; + } + Some("firefox-bin") => { + //symlink(self.directory.join("firefox"), self.directory.join("firefox-bin")).ok(); + } + Some("firefox") => { + copy( + entry.parent().expect("failed to copy firefox").join("firefox"), + self.directory.join("firefox"), + )?; + // symlink( + // self.directory.join("firefox"), + // self.directory.join("firefox-bin"), + // )?; + } + Some(&_) => { + let link = self.directory.join(entry.file_name().unwrap()); + symlink(entry, link)?; + } + None => todo!(), + } + } + } + + info!("Runtime linked!"); + Ok(()) } #[cfg(not(feature = "immutable-runtime"))] - pub fn uninstall(self) -> Result<()> { + pub fn uninstall(&self) -> Result<()> { info!("Uninstalling the runtime"); - remove_dir_contents(self.directory).context("Failed to remove runtime directory")?; + remove_dir_contents(&self.directory).context("Failed to remove runtime directory")?; info!("Runtime uninstalled!"); Ok(()) diff --git a/native/src/connector/process.rs b/native/src/connector/process.rs index c09df418..aa383773 100644 --- a/native/src/connector/process.rs +++ b/native/src/connector/process.rs @@ -83,7 +83,10 @@ impl Process for SetConfig { impl Process for InstallRuntime { fn process(&self, _connection: &Connection) -> Result { - let command = RuntimeInstallCommand {}; + let command = RuntimeInstallCommand { + #[cfg(target_os = "linux")] + link: self.link, + }; command.run()?; Ok(ConnectorResponse::RuntimeInstalled) diff --git a/native/src/connector/request.rs b/native/src/connector/request.rs index 914320ff..d7ea3d4d 100644 --- a/native/src/connector/request.rs +++ b/native/src/connector/request.rs @@ -153,8 +153,12 @@ pub struct SetConfig(pub Config); /// /// [`ConnectorResponse::RuntimeInstalled`] - No data. /// -#[derive(Debug, Eq, PartialEq, Clone)] -pub struct InstallRuntime; +#[derive(Deserialize, Debug, Eq, PartialEq, Clone)] +pub struct InstallRuntime { + #[cfg(target_os = "linux")] + /// Experimental: use a linked runtime instead of downloading from mozilla. + pub link: bool, +} /// Uninstalls the Firefox runtime. /// @@ -603,6 +607,7 @@ impl Into for HTTPClientConfig { deserialize_unit_struct!(GetSystemVersions); deserialize_unit_struct!(GetConfig); +#[cfg(not(target_os = "linux"))] deserialize_unit_struct!(InstallRuntime); deserialize_unit_struct!(UninstallRuntime); deserialize_unit_struct!(GetSiteList); diff --git a/native/src/console/app.rs b/native/src/console/app.rs index cee7ad1d..445749b7 100644 --- a/native/src/console/app.rs +++ b/native/src/console/app.rs @@ -275,7 +275,12 @@ pub enum RuntimeCommand { } #[derive(Parser, Debug, Eq, PartialEq, Clone)] -pub struct RuntimeInstallCommand {} +pub struct RuntimeInstallCommand { + /// Experimental: use a linked runtime instead of downloading from mozilla. + #[cfg(target_os = "linux")] + #[clap(long)] + pub link: bool, +} #[derive(Parser, Debug, Eq, PartialEq, Clone)] pub struct RuntimeUninstallCommand {} diff --git a/native/src/console/runtime.rs b/native/src/console/runtime.rs index ccbe4ed8..f31eac0c 100644 --- a/native/src/console/runtime.rs +++ b/native/src/console/runtime.rs @@ -25,7 +25,16 @@ impl Run for RuntimeInstallCommand { let dirs = ProjectDirs::new()?; let runtime = Runtime::new(&dirs)?; - runtime.install().context("Failed to install runtime")?; + + cfg_if! { + if #[cfg(target_os = "linux")] { + if self.link { + runtime.link().context("Failed to link runtime")? + } + } else { + runtime.install().context("Failed to install runtime")?; + } + }; let runtime = Runtime::new(&dirs)?; runtime.patch(&dirs, None)?; diff --git a/native/src/storage.rs b/native/src/storage.rs index ed76684d..f01bd2db 100644 --- a/native/src/storage.rs +++ b/native/src/storage.rs @@ -48,6 +48,11 @@ pub struct Config { /// Only affects Linux, on supported desktop environments. /// May be overwritten with a system environment variable. pub runtime_use_portals: bool, + + #[cfg(target_os = "linux")] + /// Experimental: Using the system runtime to save some disk space. + /// This might not work on your system. + pub use_linked_runtime: bool, } #[non_exhaustive] From 19773f9b14869642b2271270c47ce0fb20e87aec Mon Sep 17 00:00:00 2001 From: tiziodcaio Date: Mon, 2 Oct 2023 12:22:04 +0200 Subject: [PATCH 02/10] Fix serializing --- native/src/connector/request.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/native/src/connector/request.rs b/native/src/connector/request.rs index d7ea3d4d..6d04a0ac 100644 --- a/native/src/connector/request.rs +++ b/native/src/connector/request.rs @@ -153,13 +153,18 @@ pub struct SetConfig(pub Config); /// /// [`ConnectorResponse::RuntimeInstalled`] - No data. /// + +#[cfg(target_os = "linux")] #[derive(Deserialize, Debug, Eq, PartialEq, Clone)] pub struct InstallRuntime { - #[cfg(target_os = "linux")] /// Experimental: use a linked runtime instead of downloading from mozilla. pub link: bool, } +#[cfg(not(target_os = "linux"))] +#[derive(Debug, Eq, PartialEq, Clone)] +pub struct InstallRuntime; + /// Uninstalls the Firefox runtime. /// /// # Parameters From 9300fdc5a2ae9a5e65b22252c6b6e72cea1f6e08 Mon Sep 17 00:00:00 2001 From: tiziodcaio Date: Mon, 22 Jan 2024 18:11:51 +0100 Subject: [PATCH 03/10] Mix fixes Added "support" to BSD, needed testing Disabled when using immutable-runtime feature Removed/cleaned some branches of rust code for readability --- native/src/components/runtime.rs | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/native/src/components/runtime.rs b/native/src/components/runtime.rs index 32cd1fc4..5b8feb63 100644 --- a/native/src/components/runtime.rs +++ b/native/src/components/runtime.rs @@ -286,7 +286,7 @@ impl Runtime { Ok(()) } - #[cfg(target_os = "linux")] + #[cfg(all(any(target_os = "linux", target_os = "bsd"), not(feature = "immutable-runtime")))] pub fn link(&self) -> Result<()> { use std::fs::{copy, create_dir_all}; use std::os::unix::fs::symlink; @@ -309,16 +309,7 @@ impl Runtime { for entry in read_dir("/usr/lib/firefox/")?.flatten() { let entry = entry.path(); match entry.file_name().expect("Couldn't retrieve a file name").to_str() { - Some("browser") => { - create_dir_all(self.directory.join("browser"))?; - symlink(entry.join("chrome"), self.directory.join("browser/chrome"))?; - symlink( - entry.join("crashreporter-override.ini"), - self.directory.join("browser/crashreporter-override.ini"), - )?; - symlink(entry.join("features"), self.directory.join("browser/features"))?; - symlink(entry.join("omni.ja"), self.directory.join("browser/omni.ja"))?; - } + // Use a different branch for the "defaults" folder due to the patches to apply afterwhile Some("defaults") => { create_dir_all(self.directory.join("defaults/pref"))?; symlink( @@ -327,17 +318,10 @@ impl Runtime { )?; } Some("firefox-bin") => { - //symlink(self.directory.join("firefox"), self.directory.join("firefox-bin")).ok(); + copy(entry, self.directory.join("firefox-bin"))?; } Some("firefox") => { - copy( - entry.parent().expect("failed to copy firefox").join("firefox"), - self.directory.join("firefox"), - )?; - // symlink( - // self.directory.join("firefox"), - // self.directory.join("firefox-bin"), - // )?; + copy(entry, self.directory.join("firefox"))?; } Some(&_) => { let link = self.directory.join(entry.file_name().unwrap()); From 234daf95d996520615becaeb636ddaf238d13a70 Mon Sep 17 00:00:00 2001 From: tiziodcaio Date: Mon, 22 Jan 2024 18:15:25 +0100 Subject: [PATCH 04/10] Always uninstall after trying to link it Because otherwise it will fail due to existance of old files --- native/src/components/runtime.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/native/src/components/runtime.rs b/native/src/components/runtime.rs index 5b8feb63..7cc99bd5 100644 --- a/native/src/components/runtime.rs +++ b/native/src/components/runtime.rs @@ -296,9 +296,7 @@ impl Runtime { let dirs = ProjectDirs::new()?; let mut storage = Storage::load(&dirs)?; - if !storage.config.use_linked_runtime { - self.uninstall()?; - } + self.uninstall()?; storage.config.use_linked_runtime = true; storage.write(&dirs)?; From 101bc17381839c6a3d3e4fc58e711dc2d27a7c93 Mon Sep 17 00:00:00 2001 From: tiziodcaio Date: Tue, 23 Jan 2024 23:04:20 +0100 Subject: [PATCH 05/10] Add initial support for checksumming. --- native/Cargo.lock | 20 ++++++++++++++++++++ native/Cargo.toml | 1 + native/src/components/runtime.rs | 30 +++++++++++++++++++++++------- native/src/console/site.rs | 12 +++++++----- native/src/storage.rs | 3 ++- 5 files changed, 53 insertions(+), 13 deletions(-) diff --git a/native/Cargo.lock b/native/Cargo.lock index 191f6d2a..dea1a091 100644 --- a/native/Cargo.lock +++ b/native/Cargo.lock @@ -203,6 +203,19 @@ version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +[[package]] +name = "blake3" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0231f06152bf547e9c2b5194f247cd97aacf6dcd8b15d8e5ec0663f64580da87" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + [[package]] name = "brotli" version = "3.4.0" @@ -390,6 +403,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "constant_time_eq" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" + [[package]] name = "core-foundation" version = "0.9.4" @@ -639,6 +658,7 @@ version = "0.0.0" dependencies = [ "ab_glyph", "anyhow", + "blake3", "byteorder", "bzip2", "cfg-if", diff --git a/native/Cargo.toml b/native/Cargo.toml index 0f5f440e..5e2d6df1 100644 --- a/native/Cargo.toml +++ b/native/Cargo.toml @@ -27,6 +27,7 @@ immutable-runtime = [] [dependencies] ab_glyph = "0.2.23" anyhow = "1.0.79" +blake3 = "1.5.0" byteorder = "1.5.0" cfg-if = "1.0.0" clap = { version = "^4.4.18", features = ["derive"] } diff --git a/native/src/components/runtime.rs b/native/src/components/runtime.rs index 7cc99bd5..7546c191 100644 --- a/native/src/components/runtime.rs +++ b/native/src/components/runtime.rs @@ -1,9 +1,10 @@ -use std::fs::{read_dir, remove_dir_all, remove_file}; -use std::io::Result as IoResult; +use std::fs::{read_dir, remove_dir_all, remove_file, File}; +use std::io::{Read, Result as IoResult}; use std::path::{Path, PathBuf}; use std::process::{Child, Command}; use anyhow::{anyhow, Context, Result}; +use blake3::Hasher; use cfg_if::cfg_if; use configparser::ini::Ini; use fs_extra::dir::{copy, CopyOptions}; @@ -13,6 +14,17 @@ use tempfile::{NamedTempFile, TempDir}; use crate::components::site::Site; use crate::directories::ProjectDirs; +// TODO: Remove this constant and implement variable firefox path into user documentation +pub const FFOX: &str = "/usr/lib/firefox/"; + +pub fn b3hasher() -> String { + let mut file = File::open(Path::new(FFOX).join("firefox")).unwrap(); + let mut buf = Vec::new(); + let _ = file.read_to_end(&mut buf); + + Hasher::new().update(&buf).finalize().to_string() +} + cfg_if! { if #[cfg(any(platform_linux, platform_bsd))] { @@ -288,23 +300,21 @@ impl Runtime { #[cfg(all(any(target_os = "linux", target_os = "bsd"), not(feature = "immutable-runtime")))] pub fn link(&self) -> Result<()> { + use crate::storage::Storage; use std::fs::{copy, create_dir_all}; use std::os::unix::fs::symlink; - use crate::storage::Storage; - let dirs = ProjectDirs::new()?; let mut storage = Storage::load(&dirs)?; self.uninstall()?; storage.config.use_linked_runtime = true; - storage.write(&dirs)?; info!("Linking the runtime"); - if Path::new("/usr/lib/firefox/").exists() { - for entry in read_dir("/usr/lib/firefox/")?.flatten() { + if Path::new(FFOX).exists() { + for entry in read_dir(FFOX)?.flatten() { let entry = entry.path(); match entry.file_name().expect("Couldn't retrieve a file name").to_str() { // Use a different branch for the "defaults" folder due to the patches to apply afterwhile @@ -320,6 +330,10 @@ impl Runtime { } Some("firefox") => { copy(entry, self.directory.join("firefox"))?; + + storage.config.hash = b3hasher(); + + trace!("Hash: {}", b3hasher()); } Some(&_) => { let link = self.directory.join(entry.file_name().unwrap()); @@ -330,6 +344,8 @@ impl Runtime { } } + storage.write(&dirs)?; + info!("Runtime linked!"); Ok(()) diff --git a/native/src/console/site.rs b/native/src/console/site.rs index 9990952e..ae5730b8 100644 --- a/native/src/console/site.rs +++ b/native/src/console/site.rs @@ -12,17 +12,14 @@ use url::Url; use crate::components::runtime::Runtime; use crate::components::site::{Site, SiteConfig}; use crate::console::app::{ - SiteInstallCommand, - SiteLaunchCommand, - SiteUninstallCommand, - SiteUpdateCommand, + SiteInstallCommand, SiteLaunchCommand, SiteUninstallCommand, SiteUpdateCommand, }; use crate::console::{store_value, store_value_vec, Run}; use crate::directories::ProjectDirs; -use crate::integrations; use crate::integrations::{IntegrationInstallArgs, IntegrationUninstallArgs}; use crate::storage::Storage; use crate::utils::construct_certificates_and_client; +use crate::{components, integrations}; impl Run for SiteLaunchCommand { fn run(&self) -> Result<()> { @@ -50,6 +47,11 @@ impl Run for SiteLaunchCommand { bail!("Runtime not installed"); } + if storage.config.hash != components::runtime::b3hasher() && !storage.config.hash.is_empty() + { + runtime.link()?; + } + // Patching on macOS is always needed to correctly show the web app name // Otherwise, patch runtime and profile only if needed let should_patch = if cfg!(platform_macos) || storage.config.always_patch { diff --git a/native/src/storage.rs b/native/src/storage.rs index f01bd2db..f6424df2 100644 --- a/native/src/storage.rs +++ b/native/src/storage.rs @@ -49,10 +49,11 @@ pub struct Config { /// May be overwritten with a system environment variable. pub runtime_use_portals: bool, - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "bsd"))] /// Experimental: Using the system runtime to save some disk space. /// This might not work on your system. pub use_linked_runtime: bool, + pub hash: String, } #[non_exhaustive] From 2e249b6e5b9fc78a5f28513635769bed0df2a245 Mon Sep 17 00:00:00 2001 From: tiziodcaio Date: Fri, 26 Jan 2024 21:02:55 +0100 Subject: [PATCH 06/10] Compare instead of store an hash --- native/src/components/runtime.rs | 17 ++--------------- native/src/console/runtime.rs | 14 +++++--------- native/src/console/site.rs | 18 +++++++++++++++--- native/src/storage.rs | 1 - 4 files changed, 22 insertions(+), 28 deletions(-) diff --git a/native/src/components/runtime.rs b/native/src/components/runtime.rs index 7546c191..38902d95 100644 --- a/native/src/components/runtime.rs +++ b/native/src/components/runtime.rs @@ -1,10 +1,9 @@ -use std::fs::{read_dir, remove_dir_all, remove_file, File}; -use std::io::{Read, Result as IoResult}; +use std::fs::{read_dir, remove_dir_all, remove_file}; +use std::io::Result as IoResult; use std::path::{Path, PathBuf}; use std::process::{Child, Command}; use anyhow::{anyhow, Context, Result}; -use blake3::Hasher; use cfg_if::cfg_if; use configparser::ini::Ini; use fs_extra::dir::{copy, CopyOptions}; @@ -17,14 +16,6 @@ use crate::directories::ProjectDirs; // TODO: Remove this constant and implement variable firefox path into user documentation pub const FFOX: &str = "/usr/lib/firefox/"; -pub fn b3hasher() -> String { - let mut file = File::open(Path::new(FFOX).join("firefox")).unwrap(); - let mut buf = Vec::new(); - let _ = file.read_to_end(&mut buf); - - Hasher::new().update(&buf).finalize().to_string() -} - cfg_if! { if #[cfg(any(platform_linux, platform_bsd))] { @@ -330,10 +321,6 @@ impl Runtime { } Some("firefox") => { copy(entry, self.directory.join("firefox"))?; - - storage.config.hash = b3hasher(); - - trace!("Hash: {}", b3hasher()); } Some(&_) => { let link = self.directory.join(entry.file_name().unwrap()); diff --git a/native/src/console/runtime.rs b/native/src/console/runtime.rs index f31eac0c..12e3bdc6 100644 --- a/native/src/console/runtime.rs +++ b/native/src/console/runtime.rs @@ -26,15 +26,11 @@ impl Run for RuntimeInstallCommand { let dirs = ProjectDirs::new()?; let runtime = Runtime::new(&dirs)?; - cfg_if! { - if #[cfg(target_os = "linux")] { - if self.link { - runtime.link().context("Failed to link runtime")? - } - } else { - runtime.install().context("Failed to install runtime")?; - } - }; + if cfg!(any(linux, bsd)) && self.link { + runtime.link().context("Failed to link runtime")? + } else { + runtime.install().context("Failed to install runtime")?; + } let runtime = Runtime::new(&dirs)?; runtime.patch(&dirs, None)?; diff --git a/native/src/console/site.rs b/native/src/console/site.rs index ae5730b8..dcc61af3 100644 --- a/native/src/console/site.rs +++ b/native/src/console/site.rs @@ -1,9 +1,11 @@ use std::convert::TryInto; -use std::fs::metadata; -use std::io; +use std::fs::{metadata, File}; use std::io::Write; +use std::io::{self, Read}; +use std::path::Path; use anyhow::{bail, Context, Result}; +use blake3::{hash, Hash}; use cfg_if::cfg_if; use log::{info, warn}; use ulid::Ulid; @@ -47,7 +49,17 @@ impl Run for SiteLaunchCommand { bail!("Runtime not installed"); } - if storage.config.hash != components::runtime::b3hasher() && !storage.config.hash.is_empty() + fn hasher(path: &str) -> Hash { + let mut file = File::open(Path::new(&path).join("firefox")).unwrap(); + let mut buf = Vec::new(); + let _ = file.read_to_end(&mut buf); + + hash(&buf) + } + + if storage.config.use_linked_runtime + && hasher(components::runtime::FFOX) + != hasher("/home/daniele/.local/share/firefoxpwa/runtime/") { runtime.link()?; } diff --git a/native/src/storage.rs b/native/src/storage.rs index f6424df2..905126d4 100644 --- a/native/src/storage.rs +++ b/native/src/storage.rs @@ -53,7 +53,6 @@ pub struct Config { /// Experimental: Using the system runtime to save some disk space. /// This might not work on your system. pub use_linked_runtime: bool, - pub hash: String, } #[non_exhaustive] From 1841cc5166169320967276deba30764362939035 Mon Sep 17 00:00:00 2001 From: tiziodcaio Date: Thu, 21 Mar 2024 14:05:51 +0100 Subject: [PATCH 07/10] "Fix" borked support to bsd... --- native/src/components/runtime.rs | 2 +- native/src/connector/request.rs | 6 +++--- native/src/console/app.rs | 2 +- native/src/console/runtime.rs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/native/src/components/runtime.rs b/native/src/components/runtime.rs index 38902d95..74b117c1 100644 --- a/native/src/components/runtime.rs +++ b/native/src/components/runtime.rs @@ -289,7 +289,7 @@ impl Runtime { Ok(()) } - #[cfg(all(any(target_os = "linux", target_os = "bsd"), not(feature = "immutable-runtime")))] + #[cfg(any(target_os = "linux", target_os = "bsd"))] pub fn link(&self) -> Result<()> { use crate::storage::Storage; use std::fs::{copy, create_dir_all}; diff --git a/native/src/connector/request.rs b/native/src/connector/request.rs index 6d04a0ac..d6a5a0a1 100644 --- a/native/src/connector/request.rs +++ b/native/src/connector/request.rs @@ -154,14 +154,14 @@ pub struct SetConfig(pub Config); /// [`ConnectorResponse::RuntimeInstalled`] - No data. /// -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "bsd"))] #[derive(Deserialize, Debug, Eq, PartialEq, Clone)] pub struct InstallRuntime { /// Experimental: use a linked runtime instead of downloading from mozilla. pub link: bool, } -#[cfg(not(target_os = "linux"))] +#[cfg(not(any(target_os = "linux", target_os = "bsd")))] #[derive(Debug, Eq, PartialEq, Clone)] pub struct InstallRuntime; @@ -612,7 +612,7 @@ impl Into for HTTPClientConfig { deserialize_unit_struct!(GetSystemVersions); deserialize_unit_struct!(GetConfig); -#[cfg(not(target_os = "linux"))] +#[cfg(not(any(target_os = "linux", target_os = "bsd")))] deserialize_unit_struct!(InstallRuntime); deserialize_unit_struct!(UninstallRuntime); deserialize_unit_struct!(GetSiteList); diff --git a/native/src/console/app.rs b/native/src/console/app.rs index 445749b7..ef470817 100644 --- a/native/src/console/app.rs +++ b/native/src/console/app.rs @@ -277,7 +277,7 @@ pub enum RuntimeCommand { #[derive(Parser, Debug, Eq, PartialEq, Clone)] pub struct RuntimeInstallCommand { /// Experimental: use a linked runtime instead of downloading from mozilla. - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "bsd"))] #[clap(long)] pub link: bool, } diff --git a/native/src/console/runtime.rs b/native/src/console/runtime.rs index 12e3bdc6..44726b99 100644 --- a/native/src/console/runtime.rs +++ b/native/src/console/runtime.rs @@ -26,7 +26,7 @@ impl Run for RuntimeInstallCommand { let dirs = ProjectDirs::new()?; let runtime = Runtime::new(&dirs)?; - if cfg!(any(linux, bsd)) && self.link { + if cfg!(any(target_os = "linux", target_os = "bsd")) && self.link { runtime.link().context("Failed to link runtime")? } else { runtime.install().context("Failed to install runtime")?; From 53aca9ae0a20e070fa4f4f2ed68e5946fce2ded3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20=C5=A0?= Date: Thu, 28 Mar 2024 22:27:19 +0100 Subject: [PATCH 08/10] Discard changes to extension/src/sites/manage.js --- extension/src/sites/manage.js | 9 --------- 1 file changed, 9 deletions(-) diff --git a/extension/src/sites/manage.js b/extension/src/sites/manage.js index d831d8cc..70760a7f 100644 --- a/extension/src/sites/manage.js +++ b/extension/src/sites/manage.js @@ -865,12 +865,6 @@ async function handleSettings (hasChanged = false) { this.disabled = true this.innerText = await getMessage('buttonReinstallProcessing') - // Listen for use Linked runtime - document.getElementById('settings-use-linked-runtime').addEventListener('change', async function () { - config.use_linked_runtime = this.checked - await setConfig(config) - }) - const responseUninstall = await browser.runtime.sendNativeMessage('firefoxpwa', { cmd: 'UninstallRuntime' }) if (responseUninstall.type === 'Error') throw new Error(responseUninstall.data) if (responseUninstall.type !== 'RuntimeUninstalled') throw new Error(`Received invalid response type: ${responseUninstall.type}`) @@ -919,7 +913,6 @@ async function handleSettings (hasChanged = false) { document.getElementById('settings-enable-wayland-container').classList.remove('d-none') document.getElementById('settings-use-xinput2-container').classList.remove('d-none') document.getElementById('settings-use-portals-container').classList.remove('d-none') - document.getElementById('settings-use-linked-runtime-container').classList.remove('d-none') } // Hide patching setting on macOS @@ -934,7 +927,6 @@ async function handleSettings (hasChanged = false) { document.getElementById('settings-enable-wayland').checked = config.runtime_enable_wayland document.getElementById('settings-use-xinput2').checked = config.runtime_use_xinput2 document.getElementById('settings-use-portals').checked = config.runtime_use_portals - document.getElementById('settings-use-linked-runtime').checked = config.use_linked_runtime document.getElementById('settings-always-patch').checked = config.always_patch // Enable settings inputs @@ -945,7 +937,6 @@ async function handleSettings (hasChanged = false) { document.getElementById('settings-enable-wayland').disabled = false document.getElementById('settings-use-xinput2').disabled = false document.getElementById('settings-use-portals').disabled = false - document.getElementById('settings-use-linked-runtime').disabled = false document.getElementById('settings-always-patch').disabled = false // Helper function to update config From c788a7bc3231d66a6acd6c9ef1e3740a64f18dd6 Mon Sep 17 00:00:00 2001 From: tiziodcaio Date: Fri, 29 Mar 2024 00:23:09 +0100 Subject: [PATCH 09/10] Use a feature instead of OS checks --- native/Cargo.toml | 3 +- native/src/components/runtime.rs | 4 +-- native/src/connector/process.rs | 32 ++++---------------- native/src/connector/request.rs | 6 ++-- native/src/console/app.rs | 2 +- native/src/console/runtime.rs | 6 +++- native/src/console/site.rs | 51 ++++++++++++++++++-------------- native/src/storage.rs | 2 +- 8 files changed, 48 insertions(+), 58 deletions(-) diff --git a/native/Cargo.toml b/native/Cargo.toml index 5e2d6df1..5a6ff520 100644 --- a/native/Cargo.toml +++ b/native/Cargo.toml @@ -23,11 +23,11 @@ lto = true portable = ["dep:phf"] static = ["reqwest/native-tls-vendored", "bzip2/static"] immutable-runtime = [] +linked-runtime = ["dep:blake3"] [dependencies] ab_glyph = "0.2.23" anyhow = "1.0.79" -blake3 = "1.5.0" byteorder = "1.5.0" cfg-if = "1.0.0" clap = { version = "^4.4.18", features = ["derive"] } @@ -76,6 +76,7 @@ features = [ [target.'cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd"))'.dependencies] glob = "0.3.1" phf = { version = "0.11.2", features = ["macros"] } +blake3 = { version = "1.5.0", optional = true } [target.'cfg(target_os = "linux")'.dependencies] bzip2 = "0.4.4" diff --git a/native/src/components/runtime.rs b/native/src/components/runtime.rs index 74b117c1..e99bda36 100644 --- a/native/src/components/runtime.rs +++ b/native/src/components/runtime.rs @@ -198,7 +198,7 @@ impl Runtime { const COPY_ERROR: &str = "Failed to copy the runtime"; const CLEANUP_ERROR: &str = "Failed to clean up the runtime"; - #[cfg(target_os = "linux")] + #[cfg(feature = "linked-runtime")] { use crate::storage::Storage; @@ -289,7 +289,7 @@ impl Runtime { Ok(()) } - #[cfg(any(target_os = "linux", target_os = "bsd"))] + #[cfg(feature = "linked-runtime")] pub fn link(&self) -> Result<()> { use crate::storage::Storage; use std::fs::{copy, create_dir_all}; diff --git a/native/src/connector/process.rs b/native/src/connector/process.rs index aa383773..94cc38ef 100644 --- a/native/src/connector/process.rs +++ b/native/src/connector/process.rs @@ -4,36 +4,16 @@ use log::{info, warn}; use crate::components::runtime::Runtime; use crate::connector::request::{ - CreateProfile, - GetConfig, - GetProfileList, - GetSiteList, - GetSystemVersions, - InstallRuntime, - InstallSite, - LaunchSite, - PatchAllProfiles, - RegisterProtocolHandler, - RemoveProfile, - SetConfig, - UninstallRuntime, - UninstallSite, - UnregisterProtocolHandler, - UpdateAllSites, - UpdateProfile, + CreateProfile, GetConfig, GetProfileList, GetSiteList, GetSystemVersions, InstallRuntime, + InstallSite, LaunchSite, PatchAllProfiles, RegisterProtocolHandler, RemoveProfile, SetConfig, + UninstallRuntime, UninstallSite, UnregisterProtocolHandler, UpdateAllSites, UpdateProfile, UpdateSite, }; use crate::connector::response::ConnectorResponse; use crate::connector::Connection; use crate::console::app::{ - ProfileCreateCommand, - ProfileRemoveCommand, - ProfileUpdateCommand, - RuntimeInstallCommand, - RuntimeUninstallCommand, - SiteInstallCommand, - SiteLaunchCommand, - SiteUninstallCommand, + ProfileCreateCommand, ProfileRemoveCommand, ProfileUpdateCommand, RuntimeInstallCommand, + RuntimeUninstallCommand, SiteInstallCommand, SiteLaunchCommand, SiteUninstallCommand, SiteUpdateCommand, }; use crate::console::Run; @@ -84,7 +64,7 @@ impl Process for SetConfig { impl Process for InstallRuntime { fn process(&self, _connection: &Connection) -> Result { let command = RuntimeInstallCommand { - #[cfg(target_os = "linux")] + #[cfg(feature = "linked-runtime")] link: self.link, }; command.run()?; diff --git a/native/src/connector/request.rs b/native/src/connector/request.rs index d6a5a0a1..e448bd1d 100644 --- a/native/src/connector/request.rs +++ b/native/src/connector/request.rs @@ -154,14 +154,14 @@ pub struct SetConfig(pub Config); /// [`ConnectorResponse::RuntimeInstalled`] - No data. /// -#[cfg(any(target_os = "linux", target_os = "bsd"))] +#[cfg(feature = "linked-runtime")] #[derive(Deserialize, Debug, Eq, PartialEq, Clone)] pub struct InstallRuntime { /// Experimental: use a linked runtime instead of downloading from mozilla. pub link: bool, } -#[cfg(not(any(target_os = "linux", target_os = "bsd")))] +#[cfg(not(feature = "linked-runtime"))] #[derive(Debug, Eq, PartialEq, Clone)] pub struct InstallRuntime; @@ -612,7 +612,7 @@ impl Into for HTTPClientConfig { deserialize_unit_struct!(GetSystemVersions); deserialize_unit_struct!(GetConfig); -#[cfg(not(any(target_os = "linux", target_os = "bsd")))] +#[cfg(not(feature = "linked-runtime"))] deserialize_unit_struct!(InstallRuntime); deserialize_unit_struct!(UninstallRuntime); deserialize_unit_struct!(GetSiteList); diff --git a/native/src/console/app.rs b/native/src/console/app.rs index ef470817..9e7958d5 100644 --- a/native/src/console/app.rs +++ b/native/src/console/app.rs @@ -277,7 +277,7 @@ pub enum RuntimeCommand { #[derive(Parser, Debug, Eq, PartialEq, Clone)] pub struct RuntimeInstallCommand { /// Experimental: use a linked runtime instead of downloading from mozilla. - #[cfg(any(target_os = "linux", target_os = "bsd"))] + #[cfg(feature = "linked-runtime")] #[clap(long)] pub link: bool, } diff --git a/native/src/console/runtime.rs b/native/src/console/runtime.rs index 44726b99..79219b05 100644 --- a/native/src/console/runtime.rs +++ b/native/src/console/runtime.rs @@ -26,12 +26,16 @@ impl Run for RuntimeInstallCommand { let dirs = ProjectDirs::new()?; let runtime = Runtime::new(&dirs)?; - if cfg!(any(target_os = "linux", target_os = "bsd")) && self.link { + #[cfg(feature = "linked-runtime")] + if self.link { runtime.link().context("Failed to link runtime")? } else { runtime.install().context("Failed to install runtime")?; } + #[cfg(not(feature = "linked-runtime"))] + runtime.install().context("Failed to install runtime")?; + let runtime = Runtime::new(&dirs)?; runtime.patch(&dirs, None)?; diff --git a/native/src/console/site.rs b/native/src/console/site.rs index dcc61af3..f2da2793 100644 --- a/native/src/console/site.rs +++ b/native/src/console/site.rs @@ -1,11 +1,9 @@ use std::convert::TryInto; -use std::fs::{metadata, File}; +use std::fs::metadata; +use std::io; use std::io::Write; -use std::io::{self, Read}; -use std::path::Path; use anyhow::{bail, Context, Result}; -use blake3::{hash, Hash}; use cfg_if::cfg_if; use log::{info, warn}; use ulid::Ulid; @@ -18,10 +16,10 @@ use crate::console::app::{ }; use crate::console::{store_value, store_value_vec, Run}; use crate::directories::ProjectDirs; +use crate::integrations; use crate::integrations::{IntegrationInstallArgs, IntegrationUninstallArgs}; use crate::storage::Storage; use crate::utils::construct_certificates_and_client; -use crate::{components, integrations}; impl Run for SiteLaunchCommand { fn run(&self) -> Result<()> { @@ -31,14 +29,13 @@ impl Run for SiteLaunchCommand { let site = storage.sites.get(&self.id).context("Web app does not exist")?; let args = if !&self.arguments.is_empty() { &self.arguments } else { &storage.arguments }; - cfg_if! { - if #[cfg(platform_macos)] { - use crate::integrations; + #[cfg(platform_macos)] + { + use crate::integrations; - if !self.direct_launch { - integrations::launch(site, &self.url, args)?; - return Ok(()) - } + if !self.direct_launch { + integrations::launch(site, &self.url, args)?; + Ok(()) } } @@ -49,19 +46,27 @@ impl Run for SiteLaunchCommand { bail!("Runtime not installed"); } - fn hasher(path: &str) -> Hash { - let mut file = File::open(Path::new(&path).join("firefox")).unwrap(); - let mut buf = Vec::new(); - let _ = file.read_to_end(&mut buf); + #[cfg(feature = "linked-runtime")] + { + use blake3::{hash, Hash}; + use std::fs::File; + use std::io::Read; + use std::path::Path; + + fn hasher(path: &str) -> Hash { + let mut file = File::open(Path::new(&path).join("firefox")).unwrap(); + let mut buf = Vec::new(); + let _ = file.read_to_end(&mut buf); - hash(&buf) - } + hash(&buf) + } - if storage.config.use_linked_runtime - && hasher(components::runtime::FFOX) - != hasher("/home/daniele/.local/share/firefoxpwa/runtime/") - { - runtime.link()?; + if storage.config.use_linked_runtime + && hasher(crate::components::runtime::FFOX) + != hasher("/home/daniele/.local/share/firefoxpwa/runtime/") + { + runtime.link()?; + } } // Patching on macOS is always needed to correctly show the web app name diff --git a/native/src/storage.rs b/native/src/storage.rs index 905126d4..69cf1de8 100644 --- a/native/src/storage.rs +++ b/native/src/storage.rs @@ -49,7 +49,7 @@ pub struct Config { /// May be overwritten with a system environment variable. pub runtime_use_portals: bool, - #[cfg(any(target_os = "linux", target_os = "bsd"))] + #[cfg(feature = "linked-runtime")] /// Experimental: Using the system runtime to save some disk space. /// This might not work on your system. pub use_linked_runtime: bool, From a123e6c7d7bf82c47ef1b182fa51b291c9bc3e19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20=C5=A0?= Date: Sat, 30 Mar 2024 14:27:37 +0100 Subject: [PATCH 10/10] Reformat and fix a few problems --- native/src/components/runtime.rs | 9 +++++---- native/src/connector/process.rs | 30 +++++++++++++++++++++++++----- native/src/connector/request.rs | 2 +- native/src/console/app.rs | 2 +- native/src/console/site.rs | 19 ++++++++++--------- 5 files changed, 42 insertions(+), 20 deletions(-) diff --git a/native/src/components/runtime.rs b/native/src/components/runtime.rs index e99bda36..ced581dd 100644 --- a/native/src/components/runtime.rs +++ b/native/src/components/runtime.rs @@ -110,9 +110,9 @@ fn get_download_url() -> &'static str { pub struct Runtime { pub version: Option, - directory: PathBuf, - executable: PathBuf, - config: PathBuf, + pub directory: PathBuf, + pub executable: PathBuf, + pub config: PathBuf, } impl Runtime { @@ -291,10 +291,11 @@ impl Runtime { #[cfg(feature = "linked-runtime")] pub fn link(&self) -> Result<()> { - use crate::storage::Storage; use std::fs::{copy, create_dir_all}; use std::os::unix::fs::symlink; + use crate::storage::Storage; + let dirs = ProjectDirs::new()?; let mut storage = Storage::load(&dirs)?; diff --git a/native/src/connector/process.rs b/native/src/connector/process.rs index 94cc38ef..9e61da68 100644 --- a/native/src/connector/process.rs +++ b/native/src/connector/process.rs @@ -4,16 +4,36 @@ use log::{info, warn}; use crate::components::runtime::Runtime; use crate::connector::request::{ - CreateProfile, GetConfig, GetProfileList, GetSiteList, GetSystemVersions, InstallRuntime, - InstallSite, LaunchSite, PatchAllProfiles, RegisterProtocolHandler, RemoveProfile, SetConfig, - UninstallRuntime, UninstallSite, UnregisterProtocolHandler, UpdateAllSites, UpdateProfile, + CreateProfile, + GetConfig, + GetProfileList, + GetSiteList, + GetSystemVersions, + InstallRuntime, + InstallSite, + LaunchSite, + PatchAllProfiles, + RegisterProtocolHandler, + RemoveProfile, + SetConfig, + UninstallRuntime, + UninstallSite, + UnregisterProtocolHandler, + UpdateAllSites, + UpdateProfile, UpdateSite, }; use crate::connector::response::ConnectorResponse; use crate::connector::Connection; use crate::console::app::{ - ProfileCreateCommand, ProfileRemoveCommand, ProfileUpdateCommand, RuntimeInstallCommand, - RuntimeUninstallCommand, SiteInstallCommand, SiteLaunchCommand, SiteUninstallCommand, + ProfileCreateCommand, + ProfileRemoveCommand, + ProfileUpdateCommand, + RuntimeInstallCommand, + RuntimeUninstallCommand, + SiteInstallCommand, + SiteLaunchCommand, + SiteUninstallCommand, SiteUpdateCommand, }; use crate::console::Run; diff --git a/native/src/connector/request.rs b/native/src/connector/request.rs index e448bd1d..6dbcc60f 100644 --- a/native/src/connector/request.rs +++ b/native/src/connector/request.rs @@ -157,7 +157,7 @@ pub struct SetConfig(pub Config); #[cfg(feature = "linked-runtime")] #[derive(Deserialize, Debug, Eq, PartialEq, Clone)] pub struct InstallRuntime { - /// Experimental: use a linked runtime instead of downloading from mozilla. + /// Experimental: Use a linked runtime instead of downloading from Mozilla. pub link: bool, } diff --git a/native/src/console/app.rs b/native/src/console/app.rs index 9e7958d5..4d1fb6e3 100644 --- a/native/src/console/app.rs +++ b/native/src/console/app.rs @@ -276,7 +276,7 @@ pub enum RuntimeCommand { #[derive(Parser, Debug, Eq, PartialEq, Clone)] pub struct RuntimeInstallCommand { - /// Experimental: use a linked runtime instead of downloading from mozilla. + /// Experimental: Use a linked runtime instead of downloading from Mozilla #[cfg(feature = "linked-runtime")] #[clap(long)] pub link: bool, diff --git a/native/src/console/site.rs b/native/src/console/site.rs index f2da2793..b2ee46f7 100644 --- a/native/src/console/site.rs +++ b/native/src/console/site.rs @@ -12,7 +12,10 @@ use url::Url; use crate::components::runtime::Runtime; use crate::components::site::{Site, SiteConfig}; use crate::console::app::{ - SiteInstallCommand, SiteLaunchCommand, SiteUninstallCommand, SiteUpdateCommand, + SiteInstallCommand, + SiteLaunchCommand, + SiteUninstallCommand, + SiteUpdateCommand, }; use crate::console::{store_value, store_value_vec, Run}; use crate::directories::ProjectDirs; @@ -31,11 +34,9 @@ impl Run for SiteLaunchCommand { #[cfg(platform_macos)] { - use crate::integrations; - if !self.direct_launch { integrations::launch(site, &self.url, args)?; - Ok(()) + return Ok(()); } } @@ -48,13 +49,14 @@ impl Run for SiteLaunchCommand { #[cfg(feature = "linked-runtime")] { - use blake3::{hash, Hash}; use std::fs::File; use std::io::Read; use std::path::Path; - fn hasher(path: &str) -> Hash { - let mut file = File::open(Path::new(&path).join("firefox")).unwrap(); + use blake3::{hash, Hash}; + + fn hasher>(path: P) -> Hash { + let mut file = File::open(path.as_ref().join("firefox")).unwrap(); let mut buf = Vec::new(); let _ = file.read_to_end(&mut buf); @@ -62,8 +64,7 @@ impl Run for SiteLaunchCommand { } if storage.config.use_linked_runtime - && hasher(crate::components::runtime::FFOX) - != hasher("/home/daniele/.local/share/firefoxpwa/runtime/") + && hasher(crate::components::runtime::FFOX) != hasher(&runtime.directory) { runtime.link()?; }