mirror of
https://github.com/LibreQoE/LibreQoS.git
synced 2025-02-25 18:55:32 -06:00
More data in anonymous stats.
This commit is contained in:
parent
08e7788efb
commit
8146472479
@ -3,6 +3,18 @@
|
|||||||
/// Defines data to be submitted if anonymous usage submission is
|
/// Defines data to be submitted if anonymous usage submission is
|
||||||
/// enabled. This is protocol version 1.
|
/// enabled. This is protocol version 1.
|
||||||
pub struct AnonymousUsageV1 {
|
pub struct AnonymousUsageV1 {
|
||||||
|
/// Unique but anonymous node identifier
|
||||||
|
pub node_id: String,
|
||||||
|
|
||||||
|
/// The git hash from which this version was compiled
|
||||||
|
pub git_hash: String,
|
||||||
|
|
||||||
|
/// Are they using the Bifrost bridge?
|
||||||
|
pub using_xdp_bridge: bool,
|
||||||
|
|
||||||
|
/// Is it an "On a stick" config?
|
||||||
|
pub on_a_stick: bool,
|
||||||
|
|
||||||
/// Total installed RAM (bytes)
|
/// Total installed RAM (bytes)
|
||||||
pub total_memory: u64,
|
pub total_memory: u64,
|
||||||
|
|
||||||
@ -12,6 +24,9 @@ pub struct AnonymousUsageV1 {
|
|||||||
/// Linux Kernel Version
|
/// Linux Kernel Version
|
||||||
pub kernel_version: String,
|
pub kernel_version: String,
|
||||||
|
|
||||||
|
/// Linux distro
|
||||||
|
pub distro: String,
|
||||||
|
|
||||||
/// Number of "usable" CPU cores, as used by eBPF. This may not
|
/// Number of "usable" CPU cores, as used by eBPF. This may not
|
||||||
/// be exactly equal to the number of actual cores.
|
/// be exactly equal to the number of actual cores.
|
||||||
pub usable_cores: u32,
|
pub usable_cores: u32,
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
//! Manages the `/etc/lqos.conf` file.
|
//! Manages the `/etc/lqos.conf` file.
|
||||||
use log::error;
|
use log::error;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::path::Path;
|
use uuid::Uuid;
|
||||||
|
use std::{path::Path, fs};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
/// Represents the top-level of the `/etc/lqos.conf` file. Serialization
|
/// Represents the top-level of the `/etc/lqos.conf` file. Serialization
|
||||||
@ -15,6 +16,12 @@ pub struct EtcLqos {
|
|||||||
/// In ms.
|
/// In ms.
|
||||||
pub queue_check_period_ms: u64,
|
pub queue_check_period_ms: u64,
|
||||||
|
|
||||||
|
/// If present, provides a unique ID for the node. Used for
|
||||||
|
/// anonymous stats (to identify nodes without providing an actual
|
||||||
|
/// identity), and will be used for long-term data retention to
|
||||||
|
/// disambiguate cluster or multi-head-end nodes.
|
||||||
|
pub node_id: Option<String>,
|
||||||
|
|
||||||
/// If present, defines how the Bifrost XDP bridge operates.
|
/// If present, defines how the Bifrost XDP bridge operates.
|
||||||
pub bridge: Option<BridgeConfig>,
|
pub bridge: Option<BridgeConfig>,
|
||||||
|
|
||||||
@ -127,7 +134,10 @@ impl EtcLqos {
|
|||||||
if let Ok(raw) = std::fs::read_to_string("/etc/lqos.conf") {
|
if let Ok(raw) = std::fs::read_to_string("/etc/lqos.conf") {
|
||||||
let config_result: Result<Self, toml::de::Error> = toml::from_str(&raw);
|
let config_result: Result<Self, toml::de::Error> = toml::from_str(&raw);
|
||||||
match config_result {
|
match config_result {
|
||||||
Ok(config) => Ok(config),
|
Ok(mut config) => {
|
||||||
|
check_config(&mut config);
|
||||||
|
Ok(config)
|
||||||
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Unable to parse TOML from /etc/lqos.conf");
|
error!("Unable to parse TOML from /etc/lqos.conf");
|
||||||
error!("Full error: {:?}", e);
|
error!("Full error: {:?}", e);
|
||||||
@ -139,8 +149,50 @@ impl EtcLqos {
|
|||||||
Err(EtcLqosError::CannotReadFile)
|
Err(EtcLqosError::CannotReadFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Saves changes made to /etc/lqos.conf
|
||||||
|
/// Copies current configuration into /etc/lqos.conf.backup first
|
||||||
|
pub fn save(&self) -> Result<(), EtcLqosError> {
|
||||||
|
let cfg_path = Path::new("/etc/lqos.conf");
|
||||||
|
let backup_path = Path::new("/etc/lqos.conf.backup");
|
||||||
|
if let Err(e) = std::fs::copy(cfg_path, backup_path) {
|
||||||
|
log::error!("Unable to backup /etc/lqos.conf");
|
||||||
|
log::error!("{e:?}");
|
||||||
|
return Err(EtcLqosError::BackupFail);
|
||||||
|
}
|
||||||
|
let new_cfg = toml::to_string_pretty(&self);
|
||||||
|
match new_cfg {
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("Unable to serialize new /etc/lqos.conf");
|
||||||
|
log::error!("{e:?}");
|
||||||
|
return Err(EtcLqosError::SerializeFail);
|
||||||
|
}
|
||||||
|
Ok(new_cfg) => {
|
||||||
|
if let Err(e) = fs::write(cfg_path, new_cfg) {
|
||||||
|
log::error!("Unable to write to /etc/lqos.conf");
|
||||||
|
log::error!("{e:?}");
|
||||||
|
return Err(EtcLqosError::WriteFail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_config(cfg: &mut EtcLqos) {
|
||||||
|
let mut changed = false;
|
||||||
|
if cfg.node_id.is_none() {
|
||||||
|
let new_id = Uuid::new_v4();
|
||||||
|
cfg.node_id = Some(new_id.to_string());
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if changed {
|
||||||
|
let _ = cfg.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum EtcLqosError {
|
pub enum EtcLqosError {
|
||||||
#[error(
|
#[error(
|
||||||
@ -151,4 +203,10 @@ pub enum EtcLqosError {
|
|||||||
CannotReadFile,
|
CannotReadFile,
|
||||||
#[error("Unable to parse TOML in /etc/lqos.conf")]
|
#[error("Unable to parse TOML in /etc/lqos.conf")]
|
||||||
CannotParseToml,
|
CannotParseToml,
|
||||||
|
#[error("Unable to backup /etc/lqos.conf to /etc/lqos.conf.backup")]
|
||||||
|
BackupFail,
|
||||||
|
#[error("Unable to serialize new configuration")]
|
||||||
|
SerializeFail,
|
||||||
|
#[error("Unable to write to /etc/lqos.conf")]
|
||||||
|
WriteFail,
|
||||||
}
|
}
|
||||||
|
7
src/rust/lqosd/build.rs
Normal file
7
src/rust/lqosd/build.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
use std::process::Command;
|
||||||
|
fn main() {
|
||||||
|
// Adds a git commit hash to the program
|
||||||
|
let output = Command::new("git").args(["rev-parse", "HEAD"]).output().unwrap();
|
||||||
|
let git_hash = String::from_utf8(output.stdout).unwrap();
|
||||||
|
println!("cargo:rustc-env=GIT_HASH={}", git_hash);
|
||||||
|
}
|
@ -1,10 +1,10 @@
|
|||||||
mod lshw;
|
mod lshw;
|
||||||
|
mod version;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use lqos_bus::anonymous::AnonymousUsageV1;
|
use lqos_bus::anonymous::AnonymousUsageV1;
|
||||||
use lqos_config::{EtcLqos, LibreQoSConfig};
|
use lqos_config::{EtcLqos, LibreQoSConfig};
|
||||||
use lqos_sys::num_possible_cpus;
|
use lqos_sys::num_possible_cpus;
|
||||||
use sysinfo::{System, SystemExt, CpuExt};
|
use sysinfo::{System, SystemExt, CpuExt};
|
||||||
|
|
||||||
use crate::shaped_devices_tracker::{SHAPED_DEVICES, NETWORK_JSON};
|
use crate::shaped_devices_tracker::{SHAPED_DEVICES, NETWORK_JSON};
|
||||||
|
|
||||||
const SLOW_START_SECS: u64 = 1;
|
const SLOW_START_SECS: u64 = 1;
|
||||||
@ -44,8 +44,13 @@ fn anonymous_usage_dump() -> anyhow::Result<()> {
|
|||||||
data.cpu_vendor = cpu.vendor_id().to_string();
|
data.cpu_vendor = cpu.vendor_id().to_string();
|
||||||
data.cpu_frequency = cpu.frequency();
|
data.cpu_frequency = cpu.frequency();
|
||||||
}
|
}
|
||||||
for nic in lshw::get_nic_info()? {
|
if let Ok(nics) = lshw::get_nic_info() {
|
||||||
data.nics.push(nic.into());
|
for nic in nics {
|
||||||
|
data.nics.push(nic.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Ok(pv) = version::get_proc_version() {
|
||||||
|
data.distro = pv.trim().to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(cfg) = LibreQoSConfig::load() {
|
if let Ok(cfg) = LibreQoSConfig::load() {
|
||||||
@ -59,8 +64,19 @@ fn anonymous_usage_dump() -> anyhow::Result<()> {
|
|||||||
cfg.generated_download_mbps,
|
cfg.generated_download_mbps,
|
||||||
cfg.generated_upload_mbps,
|
cfg.generated_upload_mbps,
|
||||||
);
|
);
|
||||||
|
data.on_a_stick = cfg.on_a_stick_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Ok(cfg) = EtcLqos::load() {
|
||||||
|
if let Some(node_id) = cfg.node_id {
|
||||||
|
data.node_id = node_id;
|
||||||
|
if let Some(bridge) = cfg.bridge {
|
||||||
|
data.using_xdp_bridge = bridge.use_xdp_bridge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data.git_hash = env!("GIT_HASH").to_string();
|
||||||
data.shaped_device_count = SHAPED_DEVICES.read().unwrap().devices.len();
|
data.shaped_device_count = SHAPED_DEVICES.read().unwrap().devices.len();
|
||||||
data.net_json_len = NETWORK_JSON.read().unwrap().nodes.len();
|
data.net_json_len = NETWORK_JSON.read().unwrap().nodes.len();
|
||||||
|
|
||||||
|
9
src/rust/lqosd/src/anonymous_usage/version.rs
Normal file
9
src/rust/lqosd/src/anonymous_usage/version.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
pub(crate) fn get_proc_version() -> anyhow::Result<String> {
|
||||||
|
let output = Command::new("/bin/cat")
|
||||||
|
.args(["/proc/version"])
|
||||||
|
.output()?;
|
||||||
|
let stdout = String::from_utf8(output.stdout)?;
|
||||||
|
Ok(stdout)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user