mirror of
https://github.com/LowderPlay/cheburcheck.git
synced 2026-09-22 22:37:59 +03:00
Generated
+2
-2
@@ -2577,7 +2577,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "probe"
|
name = "probe"
|
||||||
version = "0.6.0"
|
version = "0.6.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
@@ -4652,7 +4652,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "website"
|
name = "website"
|
||||||
version = "1.3.0"
|
version = "1.3.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "probe"
|
name = "probe"
|
||||||
version = "0.6.0"
|
version = "0.6.1"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license-file = "../LICENSE"
|
license-file = "../LICENSE"
|
||||||
description = "Dynamic network probe daemon for Cheburcheck"
|
description = "Dynamic network probe daemon for Cheburcheck"
|
||||||
|
|||||||
+6
-1
@@ -76,7 +76,12 @@ detect_platform() {
|
|||||||
if command_exists apk; then
|
if command_exists apk; then
|
||||||
PLATFORM=openwrt-apk
|
PLATFORM=openwrt-apk
|
||||||
PLATFORM_NAME='OpenWrt (apk)'
|
PLATFORM_NAME='OpenWrt (apk)'
|
||||||
ARCH=$(apk --print-arch)
|
if [ -s /etc/apk/arch ]; then
|
||||||
|
ARCH=$(head -n 1 /etc/apk/arch)
|
||||||
|
else
|
||||||
|
ARCH=$(sed -n 's/^DISTRIB_ARCH=//p' /etc/openwrt_release | tr -d "'\"" | head -n 1)
|
||||||
|
fi
|
||||||
|
[ -n "$ARCH" ] || fail "OpenWrt did not report its package architecture"
|
||||||
validate_openwrt_arch "$ARCH"
|
validate_openwrt_arch "$ARCH"
|
||||||
elif command_exists opkg; then
|
elif command_exists opkg; then
|
||||||
PLATFORM=openwrt-opkg
|
PLATFORM=openwrt-opkg
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ struct Args {
|
|||||||
probe_token: String,
|
probe_token: String,
|
||||||
max_concurrent_tasks: usize,
|
max_concurrent_tasks: usize,
|
||||||
traceroute_retries: u8,
|
traceroute_retries: u8,
|
||||||
|
bundle_type: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cli {
|
impl Cli {
|
||||||
@@ -94,6 +95,7 @@ impl Cli {
|
|||||||
.context("--probe-token or PROBE_TOKEN is required when running the probe")?,
|
.context("--probe-token or PROBE_TOKEN is required when running the probe")?,
|
||||||
max_concurrent_tasks: self.max_concurrent_tasks,
|
max_concurrent_tasks: self.max_concurrent_tasks,
|
||||||
traceroute_retries: self.traceroute_retries,
|
traceroute_retries: self.traceroute_retries,
|
||||||
|
bundle_type: update::bundle_type().context("failed to detect probe bundle type")?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,6 +129,7 @@ async fn main() -> Result<()> {
|
|||||||
online: false,
|
online: false,
|
||||||
probe_id: &args.probe_id,
|
probe_id: &args.probe_id,
|
||||||
version: env!("CARGO_PKG_VERSION"),
|
version: env!("CARGO_PKG_VERSION"),
|
||||||
|
bundle_type: Some(args.bundle_type),
|
||||||
dpi_hop_v4: None,
|
dpi_hop_v4: None,
|
||||||
dpi_hop_v6: None,
|
dpi_hop_v6: None,
|
||||||
})?;
|
})?;
|
||||||
@@ -456,6 +459,7 @@ async fn publish_status(
|
|||||||
online,
|
online,
|
||||||
probe_id: &args.probe_id,
|
probe_id: &args.probe_id,
|
||||||
version: env!("CARGO_PKG_VERSION"),
|
version: env!("CARGO_PKG_VERSION"),
|
||||||
|
bundle_type: Some(args.bundle_type),
|
||||||
dpi_hop_v4: dpi_hops.v4,
|
dpi_hop_v4: dpi_hops.v4,
|
||||||
dpi_hop_v6: dpi_hops.v6,
|
dpi_hop_v6: dpi_hops.v6,
|
||||||
})?;
|
})?;
|
||||||
@@ -625,6 +629,7 @@ mod tests {
|
|||||||
online: true,
|
online: true,
|
||||||
probe_id: "probe-1",
|
probe_id: "probe-1",
|
||||||
version: "1.0.0",
|
version: "1.0.0",
|
||||||
|
bundle_type: Some("debian"),
|
||||||
dpi_hop_v4: Some(4),
|
dpi_hop_v4: Some(4),
|
||||||
dpi_hop_v6: Some(6),
|
dpi_hop_v6: Some(6),
|
||||||
};
|
};
|
||||||
@@ -632,6 +637,7 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(value["dpi_hop_v4"], 4);
|
assert_eq!(value["dpi_hop_v4"], 4);
|
||||||
assert_eq!(value["dpi_hop_v6"], 6);
|
assert_eq!(value["dpi_hop_v6"], 6);
|
||||||
|
assert_eq!(value["bundle_type"], "debian");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
+49
-6
@@ -33,6 +33,22 @@ enum PackageKind {
|
|||||||
Windows,
|
Windows,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PackageKind {
|
||||||
|
const fn bundle_type(self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Self::Debian => "debian",
|
||||||
|
Self::Apk => "openwrt-apk",
|
||||||
|
Self::Opkg => "openwrt-opkg",
|
||||||
|
Self::Linux => "linux",
|
||||||
|
Self::Windows => "windows",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bundle_type() -> Result<&'static str> {
|
||||||
|
detect_platform().map(|(kind, _, _)| kind.bundle_type())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
struct UpdateLock {
|
struct UpdateLock {
|
||||||
_file: File,
|
_file: File,
|
||||||
@@ -191,14 +207,10 @@ fn detect_platform() -> Result<(PackageKind, String, bool)> {
|
|||||||
} else if command_exists("apk")
|
} else if command_exists("apk")
|
||||||
&& command_succeeds("apk", &["info", "--exists", "cheburprobe"])?
|
&& command_succeeds("apk", &["info", "--exists", "cheburprobe"])?
|
||||||
{
|
{
|
||||||
let architecture = output_text("apk", &["--print-arch"])?;
|
let architecture = openwrt_apk_arch()?;
|
||||||
let luci_installed =
|
let luci_installed =
|
||||||
command_succeeds("apk", &["info", "--exists", "luci-app-cheburprobe"])?;
|
command_succeeds("apk", &["info", "--exists", "luci-app-cheburprobe"])?;
|
||||||
Ok((
|
Ok((PackageKind::Apk, architecture, luci_installed))
|
||||||
PackageKind::Apk,
|
|
||||||
architecture.trim().to_owned(),
|
|
||||||
luci_installed,
|
|
||||||
))
|
|
||||||
} else if command_exists("opkg")
|
} else if command_exists("opkg")
|
||||||
&& output_text("opkg", &["list-installed", "cheburprobe"])?
|
&& output_text("opkg", &["list-installed", "cheburprobe"])?
|
||||||
.lines()
|
.lines()
|
||||||
@@ -227,6 +239,28 @@ fn detect_platform() -> Result<(PackageKind, String, bool)> {
|
|||||||
bail!("updates are not supported on this operating system")
|
bail!("updates are not supported on this operating system")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
fn openwrt_apk_arch() -> Result<String> {
|
||||||
|
if let Ok(architecture) = std::fs::read_to_string("/etc/apk/arch") {
|
||||||
|
let architecture = architecture.trim();
|
||||||
|
if !architecture.is_empty() {
|
||||||
|
return Ok(architecture.to_owned());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let release = std::fs::read_to_string("/etc/openwrt_release")
|
||||||
|
.context("failed to read /etc/openwrt_release")?;
|
||||||
|
parse_openwrt_release_arch(&release).context("OpenWrt did not report DISTRIB_ARCH")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
fn parse_openwrt_release_arch(release: &str) -> Option<String> {
|
||||||
|
release.lines().find_map(|line| {
|
||||||
|
line.strip_prefix("DISTRIB_ARCH=")
|
||||||
|
.map(|value| value.trim_matches(['\'', '"']).to_owned())
|
||||||
|
.filter(|value| !value.is_empty())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn select_luci_asset<'a>(
|
fn select_luci_asset<'a>(
|
||||||
assets: &'a [Asset],
|
assets: &'a [Asset],
|
||||||
kind: PackageKind,
|
kind: PackageKind,
|
||||||
@@ -463,6 +497,15 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
#[test]
|
||||||
|
fn parses_full_openwrt_architecture() {
|
||||||
|
assert_eq!(
|
||||||
|
parse_openwrt_release_arch("DISTRIB_ID='OpenWrt'\nDISTRIB_ARCH='aarch64_cortex-a53'\n"),
|
||||||
|
Some("aarch64_cortex-a53".to_owned())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn selects_each_package_format() {
|
fn selects_each_package_format() {
|
||||||
let assets = vec![
|
let assets = vec![
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ pub struct ProbeStatus<'a> {
|
|||||||
pub probe_id: &'a str,
|
pub probe_id: &'a str,
|
||||||
pub version: &'a str,
|
pub version: &'a str,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
pub bundle_type: Option<&'a str>,
|
||||||
|
#[serde(default)]
|
||||||
pub dpi_hop_v4: Option<u8>,
|
pub dpi_hop_v4: Option<u8>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub dpi_hop_v6: Option<u8>,
|
pub dpi_hop_v6: Option<u8>,
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "website"
|
name = "website"
|
||||||
version = "1.3.0"
|
version = "1.3.1"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ struct NodeStatus {
|
|||||||
connected_at: Option<DateTime<Utc>>,
|
connected_at: Option<DateTime<Utc>>,
|
||||||
online: bool,
|
online: bool,
|
||||||
version: Option<String>,
|
version: Option<String>,
|
||||||
|
bundle_type: Option<String>,
|
||||||
dpi_hop_v4: Option<u8>,
|
dpi_hop_v4: Option<u8>,
|
||||||
dpi_hop_v6: Option<u8>,
|
dpi_hop_v6: Option<u8>,
|
||||||
}
|
}
|
||||||
@@ -107,6 +108,7 @@ fn build_node_statuses(
|
|||||||
connected_at: probe.last_connected_at,
|
connected_at: probe.last_connected_at,
|
||||||
online: status.is_some_and(|status| status.online),
|
online: status.is_some_and(|status| status.online),
|
||||||
version: status.map(|status| status.version.clone()),
|
version: status.map(|status| status.version.clone()),
|
||||||
|
bundle_type: status.and_then(|status| status.bundle_type.clone()),
|
||||||
dpi_hop_v4: status.and_then(|status| status.dpi_hop_v4),
|
dpi_hop_v4: status.and_then(|status| status.dpi_hop_v4),
|
||||||
dpi_hop_v6: status.and_then(|status| status.dpi_hop_v6),
|
dpi_hop_v6: status.and_then(|status| status.dpi_hop_v6),
|
||||||
}
|
}
|
||||||
@@ -152,6 +154,7 @@ mod tests {
|
|||||||
ProbeStatusSnapshot {
|
ProbeStatusSnapshot {
|
||||||
online: true,
|
online: true,
|
||||||
version: "1.2.3".to_string(),
|
version: "1.2.3".to_string(),
|
||||||
|
bundle_type: Some("debian".to_string()),
|
||||||
dpi_hop_v4: Some(5),
|
dpi_hop_v4: Some(5),
|
||||||
dpi_hop_v6: None,
|
dpi_hop_v6: None,
|
||||||
},
|
},
|
||||||
@@ -171,6 +174,7 @@ mod tests {
|
|||||||
connected_at: Some("2026-08-24T12:34:56Z".parse().unwrap()),
|
connected_at: Some("2026-08-24T12:34:56Z".parse().unwrap()),
|
||||||
online: true,
|
online: true,
|
||||||
version: Some("1.2.3".to_string()),
|
version: Some("1.2.3".to_string()),
|
||||||
|
bundle_type: Some("debian".to_string()),
|
||||||
dpi_hop_v4: Some(5),
|
dpi_hop_v4: Some(5),
|
||||||
dpi_hop_v6: None,
|
dpi_hop_v6: None,
|
||||||
},
|
},
|
||||||
@@ -183,6 +187,7 @@ mod tests {
|
|||||||
connected_at: Some("2026-08-23T12:34:56Z".parse().unwrap()),
|
connected_at: Some("2026-08-23T12:34:56Z".parse().unwrap()),
|
||||||
online: false,
|
online: false,
|
||||||
version: None,
|
version: None,
|
||||||
|
bundle_type: None,
|
||||||
dpi_hop_v4: None,
|
dpi_hop_v4: None,
|
||||||
dpi_hop_v6: None,
|
dpi_hop_v6: None,
|
||||||
},
|
},
|
||||||
|
|||||||
+5
-1
@@ -66,6 +66,7 @@ type ProbeStatuses = Arc<rocket::tokio::sync::RwLock<HashMap<String, ProbeStatus
|
|||||||
pub struct ProbeStatusSnapshot {
|
pub struct ProbeStatusSnapshot {
|
||||||
pub online: bool,
|
pub online: bool,
|
||||||
pub version: String,
|
pub version: String,
|
||||||
|
pub bundle_type: Option<String>,
|
||||||
pub dpi_hop_v4: Option<u8>,
|
pub dpi_hop_v4: Option<u8>,
|
||||||
pub dpi_hop_v6: Option<u8>,
|
pub dpi_hop_v6: Option<u8>,
|
||||||
}
|
}
|
||||||
@@ -377,6 +378,7 @@ async fn dispatch_probe_status(probe_statuses: &ProbeStatuses, topic: &str, payl
|
|||||||
ProbeStatusSnapshot {
|
ProbeStatusSnapshot {
|
||||||
online: status.online,
|
online: status.online,
|
||||||
version: status.version.to_string(),
|
version: status.version.to_string(),
|
||||||
|
bundle_type: status.bundle_type.map(str::to_string),
|
||||||
dpi_hop_v4: status.dpi_hop_v4,
|
dpi_hop_v4: status.dpi_hop_v4,
|
||||||
dpi_hop_v6: status.dpi_hop_v6,
|
dpi_hop_v6: status.dpi_hop_v6,
|
||||||
},
|
},
|
||||||
@@ -462,7 +464,7 @@ mod tests {
|
|||||||
dispatch_probe_status(
|
dispatch_probe_status(
|
||||||
&statuses,
|
&statuses,
|
||||||
"probe/status/v1/42",
|
"probe/status/v1/42",
|
||||||
br#"{"online":false,"probe_id":"42","version":"1.2.3","dpi_hop_v4":4,"dpi_hop_v6":6}"#,
|
br#"{"online":false,"probe_id":"42","version":"1.2.3","bundle_type":"openwrt","dpi_hop_v4":4,"dpi_hop_v6":6}"#,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@@ -471,6 +473,7 @@ mod tests {
|
|||||||
Some(&ProbeStatusSnapshot {
|
Some(&ProbeStatusSnapshot {
|
||||||
online: false,
|
online: false,
|
||||||
version: "1.2.3".to_string(),
|
version: "1.2.3".to_string(),
|
||||||
|
bundle_type: Some("openwrt".to_string()),
|
||||||
dpi_hop_v4: Some(4),
|
dpi_hop_v4: Some(4),
|
||||||
dpi_hop_v6: Some(6),
|
dpi_hop_v6: Some(6),
|
||||||
})
|
})
|
||||||
@@ -484,6 +487,7 @@ mod tests {
|
|||||||
ProbeStatusSnapshot {
|
ProbeStatusSnapshot {
|
||||||
online: true,
|
online: true,
|
||||||
version: "1.2.3".to_string(),
|
version: "1.2.3".to_string(),
|
||||||
|
bundle_type: None,
|
||||||
dpi_hop_v4: None,
|
dpi_hop_v4: None,
|
||||||
dpi_hop_v6: None,
|
dpi_hop_v6: None,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user