Add upgrade check back to the dashboard.

This commit is contained in:
Herbert Wolverson
2024-06-26 12:32:57 -05:00
parent 7117e0d5f1
commit 22c5708e63
9 changed files with 248 additions and 53 deletions

169
src/rust/Cargo.lock generated
View File

@@ -216,7 +216,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf"
dependencies = [
"async-trait",
"axum-core",
"axum-core 0.3.4",
"bitflags 1.3.2",
"bytes",
"futures-util",
@@ -241,6 +241,43 @@ dependencies = [
"tower-service",
]
[[package]]
name = "axum"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf"
dependencies = [
"async-trait",
"axum-core 0.4.3",
"base64 0.21.7",
"bytes",
"futures-util",
"http 1.1.0",
"http-body 1.0.0",
"http-body-util",
"hyper 1.3.1",
"hyper-util",
"itoa",
"matchit",
"memchr",
"mime",
"percent-encoding",
"pin-project-lite",
"rustversion",
"serde",
"serde_json",
"serde_path_to_error",
"serde_urlencoded",
"sha1",
"sync_wrapper 1.0.1",
"tokio",
"tokio-tungstenite",
"tower",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "axum-core"
version = "0.3.4"
@@ -258,6 +295,27 @@ dependencies = [
"tower-service",
]
[[package]]
name = "axum-core"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3"
dependencies = [
"async-trait",
"bytes",
"futures-util",
"http 1.1.0",
"http-body 1.0.0",
"http-body-util",
"mime",
"pin-project-lite",
"rustversion",
"sync_wrapper 0.1.2",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "backtrace"
version = "0.3.73"
@@ -805,6 +863,12 @@ dependencies = [
"parking_lot_core",
]
[[package]]
name = "data-encoding"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2"
[[package]]
name = "default-net"
version = "0.22.0"
@@ -1341,6 +1405,12 @@ dependencies = [
"pin-project-lite",
]
[[package]]
name = "http-range-header"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08a397c49fec283e3d6211adbe480be95aae5f304cfb923e9970e08956d5168a"
[[package]]
name = "httparse"
version = "1.9.4"
@@ -1396,6 +1466,7 @@ dependencies = [
"http 1.1.0",
"http-body 1.0.0",
"httparse",
"httpdate",
"itoa",
"pin-project-lite",
"smallvec",
@@ -1762,7 +1833,7 @@ name = "lqos_anonymous_stats_server"
version = "0.1.0"
dependencies = [
"anyhow",
"axum",
"axum 0.6.20",
"env_logger",
"log",
"lqos_bus",
@@ -1957,6 +2028,7 @@ name = "lqosd"
version = "0.1.0"
dependencies = [
"anyhow",
"axum 0.7.5",
"bincode",
"csv",
"dashmap",
@@ -1985,6 +2057,7 @@ dependencies = [
"sysinfo",
"thiserror",
"tokio",
"tower-http",
"zerocopy 0.6.6",
]
@@ -2094,6 +2167,16 @@ version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]]
name = "mime_guess"
version = "2.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
dependencies = [
"mime",
"unicase",
]
[[package]]
name = "minimal-lexical"
version = "0.2.1"
@@ -3221,6 +3304,17 @@ dependencies = [
"serde",
]
[[package]]
name = "sha1"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "sha2"
version = "0.10.8"
@@ -3641,6 +3735,18 @@ dependencies = [
"tokio",
]
[[package]]
name = "tokio-tungstenite"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38"
dependencies = [
"futures-util",
"log",
"tokio",
"tungstenite",
]
[[package]]
name = "tokio-util"
version = "0.7.11"
@@ -3704,6 +3810,31 @@ dependencies = [
"tracing",
]
[[package]]
name = "tower-http"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5"
dependencies = [
"bitflags 2.6.0",
"bytes",
"futures-util",
"http 1.1.0",
"http-body 1.0.0",
"http-body-util",
"http-range-header",
"httpdate",
"mime",
"mime_guess",
"percent-encoding",
"pin-project-lite",
"tokio",
"tokio-util",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower-layer"
version = "0.3.2"
@@ -3784,6 +3915,25 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "tungstenite"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1"
dependencies = [
"byteorder",
"bytes",
"data-encoding",
"http 1.1.0",
"httparse",
"log",
"rand",
"sha1",
"thiserror",
"url",
"utf-8",
]
[[package]]
name = "typenum"
version = "1.17.0"
@@ -3839,6 +3989,15 @@ dependencies = [
"version_check",
]
[[package]]
name = "unicase"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89"
dependencies = [
"version_check",
]
[[package]]
name = "unicode-bidi"
version = "0.3.15"
@@ -3911,6 +4070,12 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "utf-8"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]]
name = "utf8parse"
version = "0.2.2"

View File

@@ -2,6 +2,6 @@ mod run;
mod static_pages;
mod template;
mod ws;
mod localApi;
mod local_api;
pub use run::spawn_webserver;

View File

@@ -1,53 +1,6 @@
import {subscribeWS} from "./pubsub/ws";
import {BitsPerSecondGauge} from "./graphs/bits_gauge";
import {PacketsPerSecondBar} from "./graphs/packets_bar";
import {ShapedUnshapedPie} from "./graphs/shaped_unshaped_pie";
import {ThroughputRingBufferGraph} from "./graphs/throughput_ring_graph";
import {RttHistogram} from "./graphs/rtt_histo";
import {FlowCountGraph} from "./graphs/flows_graph";
import {Dashboard} from "./dashlets/dashboard";
import {checkForUpgrades} from "./toasts/version_check";
let tpBits = null;
let tpPackets = null;
let tpShaped = null;
let tpRing = null;
let rttHisto = null;
let tpFlows = null;
checkForUpgrades("toasts");
const dashboard = new Dashboard("dashboard");
function onMessage(msg) {
switch (msg.event) {
case "join": {
if (msg.channel === "throughput") {
tpBits = new BitsPerSecondGauge("tpBits");
tpPackets = new PacketsPerSecondBar("tpPackets");
tpShaped = new ShapedUnshapedPie("tpShaped");
tpRing = new ThroughputRingBufferGraph("tpRing");
} else if (msg.channel === "rtt") {
rttHisto = new RttHistogram("rttHisto");
} else if (msg.channel === "flows") {
tpFlows = new FlowCountGraph("tpFlows");
}
}
break;
case "throughput": {
tpBits.update(msg.data.bps[0], msg.data.bps[1], msg.data.max[0], msg.data.max[1]);
tpPackets.update(msg.data.pps[0], msg.data.pps[1]);
let shaped = msg.data.shaped_bps[0] + msg.data.shaped_bps[1];
let unshaped = msg.data.bps[0] + msg.data.bps[1];
tpShaped.update(shaped, shaped - unshaped);
tpRing.update(msg.data.shaped_bps, msg.data.bps);
}
break;
case "histogram": {
rttHisto.update(msg.data);
} break;
case "flows": {
tpFlows.update(msg.data);
}
break;
}
}
dashboard.build();
//subscribeWS(["throughput", "rtt", "flows"], onMessage);

View File

@@ -0,0 +1,11 @@
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);
}
});
}

View File

@@ -1,4 +1,5 @@
mod dashboard_themes;
mod version_check;
use axum::Router;
use axum::routing::{get, post};
@@ -9,4 +10,5 @@ pub fn local_api() -> Router {
.route("/dashletSave", post(dashboard_themes::save_theme))
.route("/dashletDelete", post(dashboard_themes::delete_theme))
.route("/dashletGet", post(dashboard_themes::get_theme))
.route("/versionCheck", get(version_check::version_check))
}

View File

@@ -0,0 +1,63 @@
use std::sync::atomic::AtomicU64;
use axum::Json;
use serde::{Deserialize, Serialize};
use lqos_config::load_config;
use lqos_utils::unix_time::unix_now;
static LAST_VERSION_CHECK: AtomicU64 = AtomicU64::new(0);
const ONE_HOUR_SECONDS: u64 = 60 * 60;
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)]
pub struct VersionCheckResponse {
update_available: bool,
}
async fn send_version_check() -> anyhow::Result<VersionCheckResponse> {
if let Ok(cfg) = load_config() {
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 response = reqwest::Client::new()
.post("https://stats.libreqos.io/api/version_check")
.json(&request)
.send()
.await?
.json()
.await?;
Ok(response)
} else {
anyhow::bail!("No config");
}
}
pub async fn version_check() -> Json<String> {
let last_check = LAST_VERSION_CHECK.load(std::sync::atomic::Ordering::Relaxed);
if let Ok(now) = unix_now() {
if now > last_check + ONE_HOUR_SECONDS {
let res = send_version_check().await;
if let Ok(response) = send_version_check().await {
LAST_VERSION_CHECK.store(now, std::sync::atomic::Ordering::Relaxed);
if response.update_available {
return Json(String::from("Update available"));
}
} else {
log::error!("Unable to send version check");
log::error!("{res:?}");
}
}
}
Json(String::from("All Good"))
}

View File

@@ -3,7 +3,7 @@ use log::info;
use tokio::net::TcpListener;
use anyhow::Result;
use crate::node_manager::{static_pages::{static_routes, vendor_route}, ws::websocket_router};
use crate::node_manager::localApi::local_api;
use crate::node_manager::local_api::local_api;
/// Launches the Axum webserver to take over node manager duties.
/// This is designed to be run as an independent Tokio future,

View File

@@ -1,3 +1,4 @@
<div id="toasts"></div>
<div class="row" id="dashboard"></div>
<script src="index.js"></script>