diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e20a10f4..2c7fef5a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,7 +3,7 @@ name: Release on: push: tags: - - "*" + - "v*" workflow_dispatch: @@ -14,64 +14,118 @@ jobs: release: name: Cross build for ${{ matrix.target }} runs-on: ${{ matrix.os }} + permissions: + contents: write strategy: matrix: include: - os: ubuntu-latest target: x86_64-unknown-linux-musl suffix: "" + use-cross: true + cargo-flags: "--no-default-features --features stat_client/native" - os: ubuntu-latest target: aarch64-unknown-linux-musl suffix: "" + use-cross: true + cargo-flags: "--no-default-features --features stat_client/native" - # - os: macos-latest - # target: x86_64-apple-darwin - # suffix: "" - # - os: macos-latest - # target: aarch64-apple-darwin - # suffix: "" + - os: ubuntu-latest + target: aarch64-linux-android + suffix: "" + use-cross: true + cargo-flags: "" + # 32bit + - os: ubuntu-latest + target: armv7-linux-androideabi + suffix: "" + use-cross: true + cargo-flags: "" + + - os: ubuntu-latest + target: armv7-unknown-linux-musleabihf + suffix: "" + use-cross: true + cargo-flags: "" + + - os: macos-latest + target: x86_64-apple-darwin + suffix: "" + use-cross: false + cargo-flags: "" + - os: macos-latest + target: aarch64-apple-darwin + suffix: "" + use-cross: true + cargo-flags: "" + + - os: windows-latest + target: x86_64-pc-windows-msvc + suffix: .exe + use-cross: false + cargo-flags: "" # - os: windows-latest - # target: x86_64-pc-windows-msvc + # target: x86_64-pc-windows-gnu # suffix: .exe + # use-cross: false + # cargo-flags: "" + steps: - uses: actions/checkout@v3 - uses: actions-rs/toolchain@v1 with: + override: true profile: minimal toolchain: stable - - name: Install cross - run: cargo install cross - - name: Run tests - run: cross test --release --target ${{ matrix.target }} --verbose + target: ${{ matrix.target }} + + - name: Install Protoc + if: matrix.os == 'windows-latest' + uses: arduino/setup-protoc@v1 + with: + version: '3.x' + repo-token: ${{ secrets.GITHUB_TOKEN }} + - name: Build release - run: cross build --release --target ${{ matrix.target }} + uses: actions-rs/cargo@v1 + with: + command: build + use-cross: ${{ matrix.use-cross }} + args: --locked --release --target=${{ matrix.target }} ${{ matrix.cargo-flags }} - - name: Install LLVM Strip - if: matrix.os == 'ubuntu-latest' - run: sudo apt-get install -y llvm + - name: Strip (MacOS/Window) + if: matrix.os != 'ubuntu-latest' + continue-on-error: true + run: | + strip target/${{ matrix.target }}/release/stat_server${{matrix.suffix}} + strip target/${{ matrix.target }}/release/stat_client${{matrix.suffix}} + cp config.toml target/${{ matrix.target }}/release/ + cp systemd/stat_server.service target/${{ matrix.target }}/release/ + cp systemd/stat_client.service target/${{ matrix.target }}/release/ - - name: LLVM Strip + - name: LLVM Strip (Linux) if: matrix.os == 'ubuntu-latest' continue-on-error: true run: | + sudo apt-get install -y llvm llvm-strip target/${{ matrix.target }}/release/stat_server${{matrix.suffix}} llvm-strip target/${{ matrix.target }}/release/stat_client${{matrix.suffix}} cp config.toml target/${{ matrix.target }}/release/ cp systemd/stat_server.service target/${{ matrix.target }}/release/ cp systemd/stat_client.service target/${{ matrix.target }}/release/ - - name: Run UPX + - name: Compress binaries # Upx may not support some platforms. Ignore the errors continue-on-error: true # Disable upx for mips. See https://github.com/upx/upx/issues/387 - if: matrix.os == 'ubuntu-latest' && !contains(matrix.target, 'mips') - uses: crazy-max/ghaction-upx@v2 + if: true && !contains(matrix.target, 'mips') + uses: svenstaro/upx-action@v2 with: - version: latest + strip: false + args: -q --best --lzma files: | target/${{ matrix.target }}/release/stat_server${{matrix.suffix}} target/${{ matrix.target }}/release/stat_client${{matrix.suffix}} - args: -q --best --lzma - uses: actions/upload-artifact@v3 with: @@ -83,8 +137,8 @@ jobs: target/${{ matrix.target }}/release/stat_server.service target/${{ matrix.target }}/release/stat_client.service - - name: Zip Release For Server - if: matrix.os == 'ubuntu-latest' + - name: Zip Release For Server (Linux) + if: matrix.os == 'ubuntu-latest' && contains(matrix.target, 'linux') uses: TheDoctor0/zip-release@0.7.1 with: type: zip @@ -95,8 +149,8 @@ jobs: stat_server.service config.toml - - name: Zip Release For Client - if: matrix.os == 'ubuntu-latest' + - name: Zip Release For Client (Linux) + if: matrix.os == 'ubuntu-latest' && contains(matrix.target, 'linux') uses: TheDoctor0/zip-release@0.7.1 with: type: zip @@ -106,20 +160,32 @@ jobs: stat_client${{matrix.suffix}} stat_client.service - # - name: Zip Release For MacOS/Win - # if: matrix.os != 'ubuntu-latest' - # uses: TheDoctor0/zip-release@0.6.2 - # with: - # type: zip - # filename: ServerStatus-${{ matrix.target }}.zip - # directory: target/${{ matrix.target }}/release/ - # path: | - # stat_server${{matrix.suffix}} - # stat_client${{matrix.suffix}} + - name: Zip Release For Server (MacOS/Window) + if: true && !contains(matrix.target, 'linux') + uses: TheDoctor0/zip-release@0.7.1 + with: + type: zip + filename: server-${{ matrix.target }}.zip + directory: target/${{ matrix.target }}/release/ + path: | + stat_server${{matrix.suffix}} + config.toml + + - name: Zip Release For Client (MacOS/Window) + if: true && !contains(matrix.target, 'linux') + uses: TheDoctor0/zip-release@0.7.1 + with: + type: zip + filename: client-${{ matrix.target }}.zip + directory: target/${{ matrix.target }}/release/ + path: | + stat_client${{matrix.suffix}} - name: Publish uses: softprops/action-gh-release@v1 if: startsWith(github.ref, 'refs/tags/') + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: files: | target/${{ matrix.target }}/release/server-${{ matrix.target }}.zip diff --git a/README.md b/README.md index 290e667c..826e1e8d 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,8 @@ `ServerStatus` 威力加强版,保持轻量和简单部署,增加以下主要特性: - 使用 `rust` 完全重写 `server`、`client`,单个执行文件部署 -- 支持上下线和简单自定义规则告警 (`telegram`、 `wechat`、 `email`、 `webhook`) +- 多系统支持 `Linux`、`MacOS`、`Windows`、`Android`、`Raspberry Pi` +- 支持上下线和简单自定义规则告警 (`telegram`、`wechat`、`email`、`webhook`) - 支持 `http` 协议上报,方便部署到各免费容器服务和配合 `cf` 等优化上报链路 - 支持 `vnstat` 统计月流量,重启不丢流量数据 - 支持 `railway` 快速部署 @@ -77,6 +78,17 @@ 📕 完整文档迁移至 [doc.ssr.rs](https://doc.ssr.rs) +| OS | Release | +| ---- | ---- | +| Linux x86_64 | x86_64-unknown-linux-musl | +| Linux arm64 | aarch64-unknown-linux-musl | +| MacOS x86_64 | x86_64-apple-darwin | +| MacOS arm64 | aarch64-apple-darwin | +| Windows x86_64 | x86_64-pc-windows-msvc | +| Raspberry Pi | armv7-unknown-linux-musleabihf | +| Android 64bit | aarch64-linux-android | +| Android 32bit | armv7-linux-androideabi | + ### 🍀 主题 如果你觉得你创造/修改的主题还不错,欢迎分享/PR,前端单独部署方法参考 [#37](https://github.com/zdz/ServerStatus-Rust/discussions/37) @@ -95,15 +107,15 @@ Hotaru 主题由 [@HinataKato](https://github.com/HinataKato) 修改提供,[ ServerStatus-web 主题由 [@mjjrock](https://github.com/mjjrock) 修改提供,[主题地址](https://github.com/mjjrock/ServerStatus-web) -演示:[Demo](https://ssr-web.vercel.app) - image
- v1.5.7版本主题 + v1.5.7 版本主题 + +[演示:Demo](https://tz-rust.vercel.app) image
@@ -123,7 +135,7 @@ bash -ex one-touch.sh ### 2.2 快速部署 -参见 [快速部署](https://doc.ssr.rs/rapid_deploy) +👉 [快速部署](https://doc.ssr.rs/rapid_deploy) ### 2.3 服务管理脚本部署,感谢 [@Colsro](https://github.com/Colsro) 提供
@@ -309,6 +321,7 @@ OPTIONS: -g, --gid group id [default: ] -h, --help Print help information --ip-info show ip info, default:false + --sys-info show sys info, default:false --json use json protocol, default:false --location location [default: ] -n, --vnstat enable vnstat, default:false @@ -321,6 +334,7 @@ OPTIONS: # 一些参数说明 --ip-info # 显示本机ip信息后立即退出,目前使用 ip-api.com 数据 +--sys-info # 显示本机系统信息后立即退出 --disable-extra # 不上报系统信息和IP信息 --disable-ping # 停用三网延时和丢包率探测 --disable-tupd # 不上报 tcp/udp/进程数/线程数,减少CPU占用 @@ -406,7 +420,7 @@ python3 stat_client.py -a "http://127.0.0.1:8080/report" -u h1 -p p1 -n
如何使用自定义主题 -更灵活的方式见 [#37](https://github.com/zdz/ServerStatus-Rust/discussions/37) +更简单的方式 👉 [#37](https://github.com/zdz/ServerStatus-Rust/discussions/37) ```nginx server { @@ -478,7 +492,7 @@ OPTIONS:
关于这个轮子 - 之前一直在使用 `Prometheus` + `Grafana` + `Alertmanager` + `node_exporter` 做VPS监控,这也是业界比较成熟的监控方案,用过一段时间后,发现非生产环境,很多监控指标都用不上,反而显得有些重。 + 之前一直在使用 `Prometheus` + `Grafana` + `Alertmanager` + `node_exporter` 做VPS监控,这也是业界比较成熟的监控方案,用过一段时间后,发现非生产环境,很多监控指标都用不上,运维成本有点大。 而 `ServerStatus` 很好,足够简单和轻量,一眼可以看尽所有小机机,只是 `c++` 版本很久没迭代过,自己的一些需求在原版上不是很好修改,如自带 `tcp` 上报对跨区机器不是很友好,也不方便对上报的链路做优化 等等。这是学习 `Rust` 练手的小项目,所以不会增加复杂功能,保持小而美,简单部署,配合 [Uptime Kuma](https://github.com/louislam/uptime-kuma) 基本上可以满足个人大部分监控需求。
diff --git a/client/Cargo.toml b/client/Cargo.toml index ecb5006b..5ecb645d 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -34,13 +34,13 @@ reqwest = {version = "0.11", features = ["json", "rustls-tls", "brotli", "gzip", serde = {version = "1.0", default-features = false, features = ["derive", "alloc"]} serde_json = {version = "1.0", default-features = false, features = ["alloc"]} stat_common = {path = "../common"} -sysinfo = "0.26" +sysinfo = "0.27.7" tokio = {version = "1", features = ["full"]} tonic = {version = "0.8", features = ["tokio-rustls"]} tower = { version = "0.4" } md5 = "0.7.0" [features] -default = ["native"] +default = ["sysinfo"] native = [] sysinfo = [] diff --git a/client/src/main.rs b/client/src/main.rs index 058bda25..4c5c52a2 100644 --- a/client/src/main.rs +++ b/client/src/main.rs @@ -86,6 +86,8 @@ pub struct Args { cm_addr: String, #[arg(long = "cu", env = "SSR_CU_ADDR", default_value = CU, help = "China Unicom probe addr")] cu_addr: String, + #[arg(long = "sys-info", help = "show sys info, default:false")] + sys_info: bool, #[arg(long = "ip-info", help = "show ip info, default:false")] ip_info: bool, #[arg(long = "json", help = "use json protocol, default:false")] @@ -155,7 +157,7 @@ fn sample_all(args: &Args, stat_base: &StatRequest) -> StatRequest { // dbg!(&stat_base); let mut stat_rt = stat_base.clone(); - #[cfg(all(feature = "native", not(feature = "sysinfo")))] + #[cfg(all(feature = "native", not(feature = "sysinfo"), target_os = "linux"))] status::sample(args, &mut stat_rt); #[cfg(all(feature = "sysinfo", not(feature = "native")))] sys_info::sample(args, &mut stat_rt); @@ -303,14 +305,19 @@ async fn main() -> Result<()> { eprintln!("sys id: {sys_id}"); eprintln!("sys info: {sys_info_json}"); + if args.sys_info { + sys_info::print_sysinfo(); + process::exit(0); + } + if let Ok(mut o) = G_CONFIG.lock() { o.sys_info = Some(sys_info); } // use native - #[cfg(all(feature = "native", not(feature = "sysinfo")))] + #[cfg(all(feature = "native", not(feature = "sysinfo"), target_os = "linux"))] { - eprintln!("enable feature native"); + eprintln!("feature native enabled"); status::start_cpu_percent_collect_t(); status::start_net_speed_collect_t(&args); } @@ -318,9 +325,9 @@ async fn main() -> Result<()> { // use sysinfo #[cfg(all(feature = "sysinfo", not(feature = "native")))] { - eprintln!("enable feature sysinfo"); + eprintln!("feature sysinfo enabled"); sys_info::start_cpu_percent_collect_t(); - sys_info::start_net_speed_collect_t(); + sys_info::start_net_speed_collect_t(&args); } status::start_all_ping_collect_t(&args); diff --git a/client/src/status.rs b/client/src/status.rs index 58a98315..a0fce2fa 100644 --- a/client/src/status.rs +++ b/client/src/status.rs @@ -1,4 +1,4 @@ -// #![allow(unused)] +#![allow(unused)] use lazy_static::lazy_static; use once_cell::sync::OnceCell; use regex::Regex; diff --git a/client/src/sys_info.rs b/client/src/sys_info.rs index 463d6b9b..17d8c4d4 100644 --- a/client/src/sys_info.rs +++ b/client/src/sys_info.rs @@ -1,11 +1,13 @@ #![deny(warnings)] #![allow(unused)] use lazy_static::lazy_static; +use std::collections::HashSet; use std::fs; use std::sync::Arc; use std::sync::Mutex; use std::thread; use std::time::Duration; +use sysinfo::CpuRefreshKind; use sysinfo::{CpuExt, DiskExt, NetworkExt, RefreshKind, System, SystemExt}; use crate::status; @@ -18,6 +20,7 @@ const SAMPLE_PERIOD: u64 = 1000; //ms lazy_static! { pub static ref G_EXPECT_FS: Vec<&'static str> = [ "apfs", + "hfs", "ext4", "ext3", "ext2", @@ -38,15 +41,15 @@ lazy_static! { pub static ref G_CPU_PERCENT: Arc> = Arc::new(Default::default()); } pub fn start_cpu_percent_collect_t() { - let mut sys = System::new_all(); - sys.refresh_cpu(); + let mut sys = System::new_with_specifics(RefreshKind::new().with_cpu(CpuRefreshKind::new().with_cpu_usage())); thread::spawn(move || loop { + sys.refresh_cpu(); + let global_cpu = sys.global_cpu_info(); if let Ok(mut cpu_percent) = G_CPU_PERCENT.lock() { *cpu_percent = global_cpu.cpu_usage().round() as f64; } - sys.refresh_cpu(); thread::sleep(Duration::from_millis(SAMPLE_PERIOD)); }); } @@ -62,8 +65,8 @@ lazy_static! { } pub fn start_net_speed_collect_t(args: &Args) { - let mut sys = System::new_all(); - sys.refresh_all(); + let mut sys = System::new_with_specifics(RefreshKind::new().with_networks().with_networks_list()); + sys.refresh_networks(); let args_1 = args.clone(); thread::spawn(move || loop { let (mut net_rx, mut net_tx) = (0_u64, 0_u64); @@ -85,19 +88,28 @@ pub fn start_net_speed_collect_t(args: &Args) { }); } -// TODO pub fn sample(args: &Args, stat: &mut StatRequest) { stat.version = env!("CARGO_PKG_VERSION").to_string(); stat.vnstat = args.vnstat; // 注意:sysinfo 统一使用 KB, 非KiB,需要转换一下 - let mut sys = System::new_with_specifics(RefreshKind::new().with_disks_list().with_memory()); + let mut unit: u64 = 1024; + + // mac系统 下面使用 KB 展示 + #[cfg(target_os = "macos")] + { + stat.si = true; + unit = 1000; + } - sys.refresh_system(); - // sys.refresh_processes(); - // sys.refresh_memory(); - // sys.refresh_disks(); - sys.refresh_disks_list(); + let mut sys = System::new_with_specifics( + RefreshKind::new() + .with_memory() + .with_disks() + .with_disks_list() + .with_networks() + .with_networks_list(), + ); // uptime stat.uptime = sys.uptime(); @@ -107,36 +119,45 @@ pub fn sample(args: &Args, stat: &mut StatRequest) { stat.load_5 = load_avg.five; stat.load_15 = load_avg.fifteen; - // mem KB -> KiB - let (mem_total, mem_used, swap_total, swap_free) = ( - sys.total_memory() * 1000 / 1024, - sys.used_memory() * 1000 / 1024, - sys.total_swap() * 1000 / 1024, - sys.free_swap() * 1000 / 1024, - ); - stat.memory_total = mem_total; - stat.memory_used = mem_used; - stat.swap_total = swap_total; - stat.swap_used = swap_total - swap_free; + // mem 不用转。。。(KB -> KiB) + stat.memory_total = sys.total_memory() / 1024; + #[cfg(any(target_os = "macos"))] + { + stat.memory_used = (sys.total_memory() - sys.available_memory()) / 1024; + } + #[cfg(not(target_os = "macos"))] + { + stat.memory_used = sys.used_memory() / 1024; + } + stat.swap_total = sys.total_swap() / 1024; + stat.swap_used = (sys.total_swap() - sys.free_swap()) / 1024; - // hdd KB -> KiB + // hdd KB -> KiB let (mut hdd_total, mut hdd_avail) = (0_u64, 0_u64); + let mut uniq_disk_set = HashSet::new(); for disk in sys.disks() { let fs = String::from_utf8_lossy(disk.file_system()).to_lowercase(); if G_EXPECT_FS.iter().any(|&k| fs.contains(k)) { + if uniq_disk_set.contains(disk.name()) { + continue; + } + uniq_disk_set.insert(disk.name()); + hdd_total += disk.total_space(); hdd_avail += disk.available_space(); } } - stat.hdd_total = hdd_total / 1024 / 1024; - stat.hdd_used = (hdd_total - hdd_avail) / 1024 / 1024; - // t/u/p/d TODO + stat.hdd_total = hdd_total / unit.pow(2); + stat.hdd_used = (hdd_total - hdd_avail) / unit.pow(2); + + // t/u/p/d let (t, u, p, d) = if args.disable_tupd { (0, 0, 0, 0) } else if "linux".eq(std::env::consts::OS) { status::tupd() } else { + // sys.processes() (0, 0, 0, 0) }; stat.tcp = t; @@ -146,13 +167,15 @@ pub fn sample(args: &Args, stat: &mut StatRequest) { // traffic if args.vnstat { - let (network_in, network_out, m_network_in, m_network_out) = vnstat::get_traffic(args).unwrap(); - stat.network_in = network_in; - stat.network_out = network_out; - stat.last_network_in = network_in - m_network_in; - stat.last_network_out = network_out - m_network_out; + #[cfg(any(target_os = "linux"))] + { + let (network_in, network_out, m_network_in, m_network_out) = vnstat::get_traffic(args).unwrap(); + stat.network_in = network_in; + stat.network_out = network_out; + stat.last_network_in = network_in - m_network_in; + stat.last_network_out = network_out - m_network_out; + } } else { - sys.refresh_networks(); let (mut network_in, mut network_out) = (0_u64, 0_u64); for (name, data) in sys.networks() { // spec iface @@ -193,8 +216,8 @@ pub fn sample(args: &Args, stat: &mut StatRequest) { pub fn collect_sys_info(args: &Args) -> SysInfo { let mut info_pb = SysInfo::default(); - let mut sys = System::new_all(); - sys.refresh_all(); + let mut sys = System::new(); + sys.refresh_cpu(); info_pb.name = args.user.to_owned(); info_pb.version = env!("CARGO_PKG_VERSION").to_string(); @@ -222,7 +245,7 @@ pub fn gen_sys_id(sys_info: &SysInfo) -> String { match fs::read_to_string(SYS_ID_FILE) { Ok(content) => { - if (content.len() > 0) { + if (!content.is_empty()) { info!("{}", format!("read sys_id from {SYS_ID_FILE}")); return content.trim().to_string(); } @@ -232,7 +255,7 @@ pub fn gen_sys_id(sys_info: &SysInfo) -> String { } } - let mut sys = System::new_all(); + let mut sys = System::new(); let bt = sys.boot_time(); let sys_id = format!( @@ -262,6 +285,67 @@ pub fn gen_sys_id(sys_info: &SysInfo) -> String { sys_id } -// pub fn get_sys_id(sys_info: &SysInfo) -> String { -// return ''.to_string(); -// } +pub fn print_sysinfo() { + use sysinfo::{NetworkExt, NetworksExt, ProcessExt, System, SystemExt}; + let mut sys = System::new_all(); + sys.refresh_all(); + + println!("=> disks:"); + for disk in sys.disks() { + println!( + "\t{}\t{}\t{}/{} B\tremovable:{}\tmounted on:{}", + disk.name().to_str().unwrap_or_default(), + String::from_utf8(disk.file_system().into()).unwrap_or_default(), + disk.available_space(), + disk.total_space(), + disk.is_removable(), + disk.mount_point().to_str().unwrap_or_default(), + ); + // println!("\t{:?}", disk); + } + + // Network interfaces name, data received and data transmitted: + println!("=> networks:"); + for (interface_name, data) in sys.networks() { + println!("\t{}: \t{}/{} B", interface_name, data.received(), data.transmitted()); + } + + // Components temperature: + println!("=> components:"); + for component in sys.components() { + println!("\t{component:?}"); + } + + println!("=> system:"); + // RAM and swap information: + println!("\ttotal memory: {} bytes", sys.total_memory()); + println!("\tused memory : {} bytes", sys.used_memory()); + println!("\tavai memory : {} bytes", sys.available_memory()); + println!("\tfree memory : {} bytes", sys.free_memory()); + println!("\ttotal swap : {} bytes", sys.total_swap()); + println!("\tused swap : {} bytes", sys.used_swap()); + + // Display system information: + println!("\tSystem name: {:?}", sys.name()); + println!("\tSystem kernel version: {:?}", sys.kernel_version()); + println!("\tSystem OS version: {:?}", sys.os_version()); + println!("\tSystem host name: {:?}", sys.host_name()); + + let load_avg = sys.load_average(); + println!( + "\tone minute: {:.2}, five minutes: {:.2}, fifteen minutes: {:.2}", + load_avg.one, load_avg.five, load_avg.fifteen, + ); + + // Number of CPUs: + let global_cpu = sys.global_cpu_info(); + println!("\tCPU Num: {}", sys.cpus().len()); + println!("\tCPU Brand: {}", global_cpu.brand()); + println!("\tCPU VerderId: {}", global_cpu.vendor_id()); + // println!("\tCPU Frequency: {}", global_cpu.frequency()); + + // Display processes ID, name na disk usage: + // for (pid, process) in sys.processes() { + // println!("[{}] {} {:?}", pid, process.name(), process.disk_usage()); + // } +} diff --git a/common/Cargo.toml b/common/Cargo.toml index dfa2473c..969b1a0a 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -1,7 +1,7 @@ [package] edition = "2021" name = "stat_common" -version = "1.1.1" +version = "1.1.2" authors = ["doge "] categories = ["monitoring-tools"] @@ -19,7 +19,11 @@ prost = "0.11" serde = {version = "1.0", default-features = false, features = ["derive", "alloc"]} tonic = {version = "0.8", features = ["tokio-rustls"]} -[build-dependencies] +[target.'cfg(not(target_env = "msvc"))'.build-dependencies] chrono = "0.4" protobuf-src = "1" tonic-build = "0.8" + +[build-dependencies] +chrono = "0.4" +tonic-build = "0.8" diff --git a/common/build.rs b/common/build.rs index 5b958af6..5b6f643b 100644 --- a/common/build.rs +++ b/common/build.rs @@ -22,7 +22,9 @@ fn main() { } println!("cargo:rustc-env=APP_VERSION={app_version}"); + #[cfg(not(target_env = "msvc"))] std::env::set_var("PROTOC", protobuf_src::protoc()); + tonic_build::configure() .type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]") .compile(&["proto/server_status.proto"], &["proto"]) diff --git a/common/proto/server_status.proto b/common/proto/server_status.proto index fb8a60f0..d60767c1 100644 --- a/common/proto/server_status.proto +++ b/common/proto/server_status.proto @@ -98,6 +98,8 @@ message StatRequest { string type = 42; string location = 43; bool notify = 44; + // false: KiB (1024), true: KB (1000) + bool si = 45; } message Response { diff --git a/config.toml b/config.toml index ada61928..312568dc 100644 --- a/config.toml +++ b/config.toml @@ -5,6 +5,7 @@ http_addr = "0.0.0.0:8080" offline_threshold = 30 # 管理员账号,不设置默认随机生成,用于查看 /detail, /map +jwt_secret = "" # 修改这个, 使用 openssl rand -base64 16 生成 secret admin_user = "" admin_pass = "" @@ -17,12 +18,18 @@ admin_pass = "" # 或国家缩写,如 cn us 等等,所有国家见目录 web/static/flags # 自定义标签 labels = "os=centos;ndd=2022/11/25;spec=2C/4G/60G;" # os 标签可选,不填则使用上报数据,ndd(next due date) 下次续费时间, spec 为主机规格 -# os 可用值 centos debian ubuntu alpine pi arch windows linux +# os 可用值 centos debian ubuntu alpine pi arch windows linux macos android hosts = [ {name = "h1", password = "p1", alias = "n1", location = "🏠", type = "kvm", labels = "os=arch;ndd=2022/11/25;spec=2C/4G/60G;"}, {name = "h2", password = "p2", alias = "n2", location = "🏢", type = "kvm", disabled = false}, {name = "h3", password = "p3", alias = "n3", location = "🏡", type = "kvm", monthstart = 1}, {name = "h4", password = "p4", alias = "n4", location = "cn", type = "kvm", notify = true, labels = "ndd=2022/11/25;spec=2C/4G/60G;"}, + + # 最小化配置 + {name = "mac", password = "pp", alias = "macos"}, + {name = "pi", password = "pp", alias = "pi", labels = "os=pi"}, + {name = "win", password = "pp", alias = "windows"}, + {name = "android", password = "pp", alias = "android", labels = "os=android"}, ] # 动态注册模式,不再需要针对每一个主机做单独配置 diff --git a/server/Cargo.toml b/server/Cargo.toml index c2253246..2cec4325 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -20,13 +20,13 @@ chrono = "0.4" [dependencies] anyhow = "1" +axum = {version = "0.6.4", features = ["headers"]} bytes = {version = "1", features = ["serde"]} chrono = "0.4" clap = {version = "4.1", features = ["derive", "unicode"]} -futures = "0.3" futures-util = {version = "0.3", default-features = false} -http-auth-basic = "0.3" hyper = {version = "0.14", features = ["full"]} +jsonwebtoken = "8.0" lazy_static = "1.4" lettre = {version = "0.10", default-features = false, features = ["smtp-transport", "pool", "hostname", "builder", "rustls-tls", "tokio1-rustls-tls"]} log = "0.4" diff --git a/server/src/stats.rs b/server/src/stats.rs index 89dec6ef..53f309bd 100644 --- a/server/src/stats.rs +++ b/server/src/stats.rs @@ -250,7 +250,9 @@ impl StatsMgr { } // labels - const OS_LIST: [&str; 7] = ["centos", "debian", "ubuntu", "pi", "arch", "windows", "linux"]; + const OS_LIST: [&str; 9] = [ + "centos", "debian", "ubuntu", "arch", "windows", "macos", "pi", "android", "linux", + ]; if !o.labels.contains("os=") { if let Some(sys_info) = &o.sys_info { let os_r = sys_info.os_release.to_lowercase();