mirror of
https://github.com/LibreQoE/LibreQoS.git
synced 2025-02-25 18:55:32 -06:00
Version checks runs in a thread separate from the UI, and the UI no longer has to wait for a version check to happen.
This commit is contained in:
34
src/rust/Cargo.lock
generated
34
src/rust/Cargo.lock
generated
@@ -2105,6 +2105,7 @@ dependencies = [
|
||||
"tower-http",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"ureq",
|
||||
"uuid",
|
||||
"zerocopy 0.8.9",
|
||||
]
|
||||
@@ -2980,11 +2981,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.23.16"
|
||||
version = "0.23.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eee87ff5d9b36712a58574e12e9f0ea80f915a5b0ac518d322b24a465617925e"
|
||||
checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b"
|
||||
dependencies = [
|
||||
"log",
|
||||
"once_cell",
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
"rustls-webpki",
|
||||
"subtle",
|
||||
@@ -3946,6 +3949,24 @@ version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||
|
||||
[[package]]
|
||||
name = "ureq"
|
||||
version = "2.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"flate2",
|
||||
"log",
|
||||
"once_cell",
|
||||
"rustls",
|
||||
"rustls-pki-types",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"url",
|
||||
"webpki-roots",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.5.3"
|
||||
@@ -4112,6 +4133,15 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.26.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
||||
@@ -61,3 +61,4 @@ allocative_derive = "0.3.3"
|
||||
#[target.'cfg(any(target_arch = "x86", target_arch = "x86_64"))'.dependencies]
|
||||
#jemallocator = { workspace = true }
|
||||
mimalloc = { workspace = true }
|
||||
ureq = { version = "2.12.1", features = ["json"] }
|
||||
|
||||
@@ -16,6 +16,7 @@ mod system_stats;
|
||||
mod blackboard;
|
||||
mod remote_commands;
|
||||
pub mod lts2_sys;
|
||||
mod version_checks;
|
||||
|
||||
#[cfg(feature = "flamegraphs")]
|
||||
use std::io::Write;
|
||||
@@ -164,6 +165,7 @@ fn main() -> Result<()> {
|
||||
throughput_tracker::spawn_throughput_monitor(long_term_stats_tx.clone(), flow_tx, system_usage_tx.clone())?;
|
||||
spawn_queue_monitor()?;
|
||||
lqos_sys::bpf_garbage_collector();
|
||||
version_checks::start_version_check()?;
|
||||
|
||||
// Handle signals
|
||||
let mut signals = Signals::new([SIGINT, SIGHUP, SIGTERM])?;
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
export function checkForUpgrades(parentId) {
|
||||
$.get("/local-api/versionCheck", (data) => {
|
||||
if (data === "Update available") {
|
||||
let div = document.createElement("div");
|
||||
div.innerHTML = "<i class='fa fa-info-circle'></i> A New Version of LibreQoS is Available";
|
||||
div.classList.add("alert", "alert-success");
|
||||
let parent = document.getElementById(parentId);
|
||||
parent.appendChild(div);
|
||||
}
|
||||
});
|
||||
if (window.newVersion) {
|
||||
let div = document.createElement("div");
|
||||
div.innerHTML = "<i class='fa fa-info-circle'></i> A New Version of LibreQoS is Available";
|
||||
div.classList.add("alert", "alert-success");
|
||||
let parent = document.getElementById(parentId);
|
||||
parent.appendChild(div);
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,14 @@ const LTS1_LINK_OFFER_TRIAL: &str = r#"
|
||||
</li>
|
||||
"#;
|
||||
|
||||
fn js_tf(b: bool) -> &'static str {
|
||||
if b {
|
||||
"true"
|
||||
} else {
|
||||
"false"
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn apply_templates(
|
||||
jar: CookieJar,
|
||||
req: Request<axum::body::Body>,
|
||||
@@ -68,7 +76,10 @@ pub async fn apply_templates(
|
||||
let template_text = template_text.replace("%%USERNAME%%", &username);
|
||||
|
||||
let res = next.run(req).await;
|
||||
let mut lts_script = "<script>window.hasLts = false;</script>";
|
||||
//let mut lts_script = "<script>window.hasLts = false;</script>";
|
||||
let mut script_has_lts = false;
|
||||
let mut script_has_insight = false;
|
||||
let new_version = crate::version_checks::new_version_available();
|
||||
|
||||
if apply_template {
|
||||
// Check to see if the box is participating in the Insight Alpha Test
|
||||
@@ -84,20 +95,23 @@ pub async fn apply_templates(
|
||||
_ => {
|
||||
// Link to it
|
||||
trial_link = INSIGHT_LINK_ACTIVE.to_string();
|
||||
lts_script = "<script>window.hasLts = true; window.hasInsight = true;</script>";
|
||||
script_has_insight = true;
|
||||
script_has_lts = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if config.long_term_stats.gather_stats && config.long_term_stats.license_key.is_some() {
|
||||
// LTS is enabled
|
||||
trial_link = LTS1_LINK_ACTIVE.to_string();
|
||||
lts_script = "<script>window.hasLts = true; window.hasInsight = false;</script>";
|
||||
script_has_lts = true;
|
||||
script_has_insight = false;
|
||||
} else {
|
||||
trial_link = LTS1_LINK_OFFER_TRIAL.replace(
|
||||
"%%LTS_TRIAL_LINK%%",
|
||||
&format!("https://stats.libreqos.io/trial1/{}", config.node_id)
|
||||
);
|
||||
lts_script = "<script>window.hasLts = false; window.hasInsight = false;</script>";
|
||||
script_has_insight = false;
|
||||
script_has_insight = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,6 +121,10 @@ pub async fn apply_templates(
|
||||
title = config.node_name.clone();
|
||||
}
|
||||
|
||||
// "LTS script" - which is increasingly becoming a misnomer
|
||||
let lts_script = format!("<script>window.hasLts = {}; window.hasInsight = {}; window.newVersion = {};</script>",
|
||||
js_tf(script_has_lts), js_tf(script_has_insight), js_tf(new_version));
|
||||
|
||||
let (mut res_parts, res_body) = res.into_parts();
|
||||
let bytes = to_bytes(res_body, 1_000_000).await.unwrap();
|
||||
let byte_string = String::from_utf8_lossy(&bytes).to_string();
|
||||
@@ -115,7 +133,7 @@ pub async fn apply_templates(
|
||||
.replace("%%VERSION%%", VERSION_STRING)
|
||||
.replace("%%TITLE%%", &title)
|
||||
.replace("%%LTS_LINK%%", &trial_link)
|
||||
.replace("%%%LTS_SCRIPT%%%", lts_script);
|
||||
.replace("%%%LTS_SCRIPT%%%", <s_script);
|
||||
if let Some(length) = res_parts.headers.get_mut("content-length") {
|
||||
*length = HeaderValue::from(byte_string.len());
|
||||
}
|
||||
|
||||
65
src/rust/lqosd/src/version_checks.rs
Normal file
65
src/rust/lqosd/src/version_checks.rs
Normal file
@@ -0,0 +1,65 @@
|
||||
//! Moves version checking out of the web system and into its
|
||||
//! own module/thread/actor. This removes any delay when the
|
||||
//! web system is running without Internet access.
|
||||
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::thread;
|
||||
use anyhow::Result;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
const VERSION_STRING: &str = include_str!("../../../VERSION_STRING");
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct VersionCheckRequest {
|
||||
current_git_hash: String,
|
||||
version_string: String,
|
||||
node_id: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, Default)]
|
||||
pub struct VersionCheckResponse {
|
||||
update_available: bool,
|
||||
}
|
||||
|
||||
static NEW_VERSION_AVAILABLE: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
/// Initializes the version checking system.
|
||||
pub fn start_version_check() -> Result<()> {
|
||||
thread::Builder::new()
|
||||
.name("version_check".to_string())
|
||||
.spawn(|| {
|
||||
loop {
|
||||
let Ok(cfg) = lqos_config::load_config() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let current_hash = env!("GIT_HASH");
|
||||
let request = VersionCheckRequest {
|
||||
current_git_hash: current_hash.to_string(),
|
||||
version_string: VERSION_STRING.to_string(),
|
||||
node_id: cfg.node_id.to_string(),
|
||||
};
|
||||
|
||||
let update_available = check_version(request).unwrap_or(false);
|
||||
NEW_VERSION_AVAILABLE.store(update_available, std::sync::atomic::Ordering::Relaxed);
|
||||
|
||||
// Sleep for 12 hours
|
||||
thread::sleep(std::time::Duration::from_secs(12 * 60 * 60));
|
||||
}
|
||||
})
|
||||
.expect("Failed to start version check thread");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns true if a new version is available.
|
||||
pub fn new_version_available() -> bool {
|
||||
NEW_VERSION_AVAILABLE.load(std::sync::atomic::Ordering::Relaxed)
|
||||
}
|
||||
|
||||
fn check_version(request: VersionCheckRequest) -> Result<bool> {
|
||||
let response: VersionCheckResponse = ureq::post("https://insight.libreqos.com/shaper_api/version_check")
|
||||
.send_json(serde_json::to_value(&request)?)?
|
||||
.into_json()?;
|
||||
Ok(response.update_available)
|
||||
}
|
||||
Reference in New Issue
Block a user