feat: compress debug snapshots into .tar.gz, include system info in them

GitHub does not allow plain .tar uploads but allows .tar.gz
This commit is contained in:
Ilya Zlobintsev 2024-02-04 23:54:18 +02:00
parent 519b4b1b15
commit 1bbea44dc2
4 changed files with 105 additions and 5 deletions

72
Cargo.lock generated
View File

@ -17,6 +17,12 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "adler32"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
[[package]] [[package]]
name = "ahash" name = "ahash"
version = "0.8.7" version = "0.8.7"
@ -528,6 +534,15 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "core2"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.2.12" version = "0.2.12"
@ -537,6 +552,15 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "crc32fast"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
dependencies = [
"cfg-if",
]
[[package]] [[package]]
name = "crossbeam-queue" name = "crossbeam-queue"
version = "0.3.11" version = "0.3.11"
@ -603,6 +627,12 @@ dependencies = [
"syn 2.0.48", "syn 2.0.48",
] ]
[[package]]
name = "dary_heap"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7762d17f1241643615821a8455a0b2c3e803784b058693d990b11f2dce25a0ca"
[[package]] [[package]]
name = "derivative" name = "derivative"
version = "2.2.0" version = "2.2.0"
@ -1160,6 +1190,15 @@ dependencies = [
"crunchy", "crunchy",
] ]
[[package]]
name = "hashbrown"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
dependencies = [
"ahash",
]
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.14.3" version = "0.14.3"
@ -1220,7 +1259,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown", "hashbrown 0.14.3",
"serde", "serde",
] ]
@ -1303,6 +1342,7 @@ dependencies = [
"futures", "futures",
"lact-schema", "lact-schema",
"libdrm_amdgpu_sys", "libdrm_amdgpu_sys",
"libflate",
"nix 0.27.1", "nix 0.27.1",
"os-release", "os-release",
"pciid-parser", "pciid-parser",
@ -1398,6 +1438,30 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "libflate"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f7d5654ae1795afc7ff76f4365c2c8791b0feb18e8996a96adad8ffd7c3b2bf"
dependencies = [
"adler32",
"core2",
"crc32fast",
"dary_heap",
"libflate_lz77",
]
[[package]]
name = "libflate_lz77"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be5f52fb8c451576ec6b79d3f4deb327398bc05bbdbd99021a6e77a4c855d524"
dependencies = [
"core2",
"hashbrown 0.13.2",
"rle-decode-fast",
]
[[package]] [[package]]
name = "libloading" name = "libloading"
version = "0.7.4" version = "0.7.4"
@ -1886,6 +1950,12 @@ version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]]
name = "rle-decode-fast"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422"
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.23" version = "0.1.23"

View File

@ -36,5 +36,6 @@ futures = { version = "0.3.30", default-features = false }
zbus = { version = "3.14.1", default-features = false, features = ["tokio"] } zbus = { version = "3.14.1", default-features = false, features = ["tokio"] }
libdrm_amdgpu_sys = { optional = true, version = "0.5.0" } libdrm_amdgpu_sys = { optional = true, version = "0.5.0" }
tar = "0.4.40" tar = "0.4.40"
libflate = "2.0.0"
chrono = "0.4.31" chrono = "0.4.31"
os-release = "0.1.0" os-release = "0.1.0"

View File

@ -1,6 +1,6 @@
use super::{ use super::{
gpu_controller::{fan_control::FanCurve, GpuController}, gpu_controller::{fan_control::FanCurve, GpuController},
system::PP_FEATURE_MASK_PATH, system::{self, detect_initramfs_type, PP_FEATURE_MASK_PATH},
}; };
use crate::config::{self, default_fan_static_speed, Config, FanControlSettings}; use crate::config::{self, default_fan_static_speed, Config, FanControlSettings};
use amdgpu_sysfs::{ use amdgpu_sysfs::{
@ -14,6 +14,9 @@ use lact_schema::{
ClocksInfo, DeviceInfo, DeviceListEntry, DeviceStats, FanControlMode, FanCurveMap, PmfwOptions, ClocksInfo, DeviceInfo, DeviceListEntry, DeviceStats, FanControlMode, FanCurveMap, PmfwOptions,
PowerStates, PowerStates,
}; };
use libflate::gzip;
use os_release::OS_RELEASE;
use serde_json::json;
use std::{ use std::{
cell::RefCell, cell::RefCell,
collections::BTreeMap, collections::BTreeMap,
@ -432,11 +435,12 @@ impl<'a> Handler {
pub fn generate_snapshot(&self) -> anyhow::Result<String> { pub fn generate_snapshot(&self) -> anyhow::Result<String> {
let datetime = chrono::Local::now().format("%Y%m%d-%H%M%S"); let datetime = chrono::Local::now().format("%Y%m%d-%H%M%S");
let out_path = format!("/tmp/LACT-sysfs-snapshot-{datetime}.tar"); let out_path = format!("/tmp/LACT-sysfs-snapshot-{datetime}.tar.gz");
let out_file = File::create(&out_path) let out_file = File::create(&out_path)
.with_context(|| "Could not create output file at {out_path}")?; .with_context(|| "Could not create output file at {out_path}")?;
let out_writer = BufWriter::new(out_file); let out_writer = gzip::Encoder::new(BufWriter::new(out_file))
.context("Could not create GZIP encoder")?;
let mut archive = tar::Builder::new(out_writer); let mut archive = tar::Builder::new(out_writer);
@ -481,10 +485,35 @@ impl<'a> Handler {
} }
} }
let system_info = system::info()
.ok()
.map(|info| serde_json::to_value(info).unwrap());
let initramfs_type = match OS_RELEASE.as_ref() {
Ok(os_release) => detect_initramfs_type(os_release)
.map(|initramfs_type| serde_json::to_value(initramfs_type).unwrap()),
Err(err) => Some(err.to_string().into()),
};
let info = json!({
"system_info": system_info,
"initramfs_type": initramfs_type,
});
let info_data = serde_json::to_vec_pretty(&info).unwrap();
let mut info_header = tar::Header::new_gnu();
info_header.set_size(info_data.len().try_into().unwrap());
info_header.set_mode(0o755);
info_header.set_cksum();
archive.append_data(&mut info_header, "info.json", Cursor::new(info_data))?;
let mut writer = archive.into_inner().context("Could not finish archive")?; let mut writer = archive.into_inner().context("Could not finish archive")?;
writer.flush().context("Could not flush output file")?; writer.flush().context("Could not flush output file")?;
writer writer
.finish()
.into_result()
.context("Could not finish GZIP archive")?
.into_inner()? .into_inner()?
.set_permissions(Permissions::from_mode(0o775)) .set_permissions(Permissions::from_mode(0o775))
.context("Could not set permissions on output file")?; .context("Could not set permissions on output file")?;

View File

@ -115,7 +115,7 @@ fn regenerate_initramfs() -> anyhow::Result<InitramfsType> {
} }
} }
fn detect_initramfs_type(os_release: &OsRelease) -> Option<InitramfsType> { pub(crate) fn detect_initramfs_type(os_release: &OsRelease) -> Option<InitramfsType> {
let id_like: Vec<_> = os_release.id_like.split_whitespace().collect(); let id_like: Vec<_> = os_release.id_like.split_whitespace().collect();
if os_release.id == "debian" || id_like.contains(&"debian") { if os_release.id == "debian" || id_like.contains(&"debian") {