diff --git a/Cargo.lock b/Cargo.lock index 2311671..43b950f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -126,9 +126,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bitflags" -version = "2.12.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84d7ced0ae9557296835c32bf1b1e02b44c746701f898460fb000d7eaa84f00a" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" [[package]] name = "blake2b_simd" @@ -321,7 +321,7 @@ dependencies = [ [[package]] name = "dkl" version = "1.2.1" -source = "git+https://novit.tech/direktil/dkl#97c25f6b20e85af5544c51ed1bcb93b9e10594f5" +source = "git+https://novit.tech/direktil/dkl#34a77eb436f104b77e9ab3d9396b4f452b8cca34" dependencies = [ "async-compression", "base32", @@ -618,9 +618,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "http" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be7462df143984c4598a256ef469b251d7d7f9e271135073e78fc535414f3d0" +checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" dependencies = [ "bytes", "itoa", @@ -989,13 +989,12 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.99" +version = "0.3.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" +checksum = "f2025f20d7a4fa7785846e7b63d10a76d3f1cee98ee5cb79ea59703f95e42162" dependencies = [ "cfg-if", "futures-util", - "once_cell", "wasm-bindgen", ] @@ -1291,9 +1290,9 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "regex" -version = "1.12.3" +version = "1.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" dependencies = [ "aho-corasick", "memchr", @@ -1314,9 +1313,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "reqwest" @@ -2006,9 +2005,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.122" +version = "0.2.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" +checksum = "a254a4b10c19a76f09a27640e7ffbf9bc30bf67e16a3bf28aaefa4920fe81563" dependencies = [ "cfg-if", "once_cell", @@ -2019,9 +2018,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.72" +version = "0.4.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9473dbd2991ae90b6291c3c32c30c6187ac49aa32f9905d1cce280ec1e110b0f" +checksum = "54568702fabf5d4849ce2b90fadfa64168a097eaf4b351ce9df8b687a0086aaf" dependencies = [ "js-sys", "wasm-bindgen", @@ -2029,9 +2028,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.122" +version = "0.2.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" +checksum = "24a40fc75b0ec6f3746ceb10d36f53a93dcd68a93b11b6445983945d79eba0dc" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2039,9 +2038,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.122" +version = "0.2.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" +checksum = "908f34bd9b9ce3d4caf07b72dfab63d61504d156856c6bd3cd87fa350cf3985b" dependencies = [ "bumpalo", "proc-macro2", @@ -2052,9 +2051,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.122" +version = "0.2.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" +checksum = "7acbf7616c27b194bbb550bf77ed0c2c3e5b7fd1260a93082b95fb7f47959b92" dependencies = [ "unicode-ident", ] @@ -2108,9 +2107,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.99" +version = "0.3.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621441cfc37b84979402712047321980c178f299193a3589d05b99e8763436" +checksum = "6e0871acf327f283dc6da28a1696cdc64fb355ba9f935d052021fa77f35cce69" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/build.rs b/build.rs index 2928225..90d5f42 100644 --- a/build.rs +++ b/build.rs @@ -1,7 +1,7 @@ use std::process::Command; fn main() { let output = Command::new("git") - .args(&["rev-parse", "HEAD"]) + .args(["rev-parse", "HEAD"]) .output() .unwrap(); let git_commit = String::from_utf8(output.stdout).unwrap(); diff --git a/src/cmd/init.rs b/src/cmd/init.rs index f842461..78d9d18 100644 --- a/src/cmd/init.rs +++ b/src/cmd/init.rs @@ -1,4 +1,4 @@ -use eyre::{format_err, Result}; +use eyre::{Result, format_err}; use log::{error, info, warn}; use std::collections::BTreeSet as Set; use std::convert::Infallible; @@ -209,6 +209,8 @@ async fn mount>( is_file = (fs::metadata(src).await) .map_err(|e| format_err!("stat {src} failed: {e}"))? .is_file(); + + #[allow(clippy::single_match)] // may be extended later match fstype { "ext4" => { exec("fsck.ext4", &["-p", src]).await; @@ -385,9 +387,9 @@ fn cmd_str(prog: &str, args: &[&str]) -> (String, Command) { #[allow(unused)] async fn child_reaper() { - use nix::sys::wait::{waitpid, WaitPidFlag}; + use nix::sys::wait::{WaitPidFlag, waitpid}; use nix::unistd::Pid; - use tokio::signal::unix::{signal, SignalKind}; + use tokio::signal::unix::{SignalKind, signal}; let Ok(mut sigs) = signal(SignalKind::child()).inspect_err(|e| warn!("failed to setup SIGCHLD handler: {e}")) @@ -405,7 +407,7 @@ async fn switch_root(root: &str) -> Result { info!("killing all processes and switching root"); dklog::LOG.close().await; - use nix::sys::signal::{kill, SIGKILL}; + use nix::sys::signal::{SIGKILL, kill}; use nix::unistd::Pid; if let Err(e) = kill(Pid::from_raw(-1), SIGKILL) { diff --git a/src/cmd/init/bootstrap.rs b/src/cmd/init/bootstrap.rs index 1214fe2..46d32df 100644 --- a/src/cmd/init/bootstrap.rs +++ b/src/cmd/init/bootstrap.rs @@ -1,4 +1,4 @@ -use eyre::{format_err, Result}; +use eyre::{Result, format_err}; use log::{debug, info, warn}; use std::path::{Path, PathBuf}; use tokio::{ @@ -49,7 +49,7 @@ pub async fn bootstrap(cfg: Config) { .await; let sys_cfg: dkl::Config = retry(async || { - let sys_cfg_bytes = seed_config(base_dir, &bs, &verifier).await?; + let sys_cfg_bytes = seed_config(base_dir, bs, &verifier).await?; Ok(serde_yaml::from_slice(&sys_cfg_bytes)?) }) .await; @@ -117,7 +117,7 @@ impl Verifier { let pubkey = base64_decode(pubkey)?; let pubkey = Some(pubkey); - return Ok(Self { pubkey }); + Ok(Self { pubkey }) } async fn verify_path(&self, path: impl AsRef) -> Result> { @@ -311,7 +311,7 @@ impl LayerMounter<'_> { .await .map_err(|e| format_err!("write {}: {e}", tgt.display()))?; - let dm_name = &format!("system"); + let dm_name = "system"; let mut cmd = tokio::process::Command::new("veritysetup"); cmd.arg("open") @@ -504,8 +504,10 @@ async fn mount_filesystems(mounts: &[dkl::Mount], root: &str) { } async fn setup_root_user(user: &dkl::RootUser, root: &str) -> Result<()> { - if let Some(pw_hash) = user.password_hash.as_ref().filter(|v| !v.is_empty()) { - set_user_password("root", &pw_hash, root).await?; + if let Some(pw_hash) = user.password_hash.as_ref() + && !pw_hash.is_empty() + { + set_user_password("root", pw_hash, root).await?; } let mut authorized_keys = Vec::new(); diff --git a/src/cmd/init/dmcrypt.rs b/src/cmd/init/dmcrypt.rs index 3d74a51..da34d10 100644 --- a/src/cmd/init/dmcrypt.rs +++ b/src/cmd/init/dmcrypt.rs @@ -1,4 +1,4 @@ -use eyre::{format_err, Result}; +use eyre::{Result, format_err}; use log::{error, info, warn}; use std::collections::BTreeSet as Set; use std::process::Stdio; @@ -6,7 +6,7 @@ use tokio::io::AsyncWriteExt; use tokio::process::Command; use tokio::sync::Mutex; -use super::{retry_or_ignore, USED_DEVS}; +use super::{USED_DEVS, retry_or_ignore}; use crate::blockdev::{is_uninitialized, uninitialize}; use crate::fs::walk_dir; use crate::input; diff --git a/src/cmd/init/lvm.rs b/src/cmd/init/lvm.rs index 520669e..dafebf4 100644 --- a/src/cmd/init/lvm.rs +++ b/src/cmd/init/lvm.rs @@ -1,8 +1,8 @@ -use eyre::{format_err, Result}; +use eyre::{Result, format_err}; use log::{error, info, warn}; use tokio::process::Command; -use super::{exec, retry, retry_or_ignore, USED_DEVS}; +use super::{USED_DEVS, exec, retry, retry_or_ignore}; use crate::fs::walk_dir; use crate::{blockdev, lvm}; use dkl::bootstrap::{Config, Filesystem, LvSize, LvmLV, LvmPV, LvmVG, TAKE_ALL}; @@ -31,7 +31,7 @@ pub async fn setup(cfg: &Config) { if (lvs.iter()).any(|lv| lv.equal_name(vg_name, lv_name)) { info!("LVM LV {vg_name}/{lv_name} exists"); } else { - retry_or_ignore(async || setup_lv(&vg, &lv).await).await; + retry_or_ignore(async || setup_lv(vg, lv).await).await; } } } @@ -40,7 +40,7 @@ pub async fn setup(cfg: &Config) { for vg in &cfg.lvm { for lv in &vg.lvs { - retry_or_ignore(async || format_lv(&vg, &lv).await).await; + retry_or_ignore(async || format_lv(vg, lv).await).await; } } } @@ -115,20 +115,20 @@ async fn setup_lv(vg: &LvmVG, lv: &LvmLV) -> Result<()> { let mut cmd = Command::new("lvcreate"); cmd.arg(&vg.name); - cmd.args(&["--name", &lv.name]); + cmd.args(["--name", &lv.name]); match &lv.size { - LvSize::Size(sz) => cmd.args(&["-L", sz]), - LvSize::Extents(sz) => cmd.args(&["-l", sz]), + LvSize::Size(sz) => cmd.args(["-L", sz]), + LvSize::Extents(sz) => cmd.args(["-l", sz]), }; let raid = lv.raid.as_ref().unwrap_or(&vg.defaults.raid); if let Some(mirrors) = raid.mirrors { - cmd.args(&["--mirrors", &mirrors.to_string()]); + cmd.args(["--mirrors", &mirrors.to_string()]); } if let Some(stripes) = raid.stripes { - cmd.args(&["--stripes", &stripes.to_string()]); + cmd.args(["--stripes", &stripes.to_string()]); } let status = cmd.status().await?; @@ -147,7 +147,7 @@ async fn format_lv(vg: &LvmVG, lv: &LvmLV) -> Result<()> { let name = &format!("{}/{}", vg.name, lv.name); let dev = &format!("/dev/{name}"); - if !blockdev::is_uninitialized(&dev).await? { + if !blockdev::is_uninitialized(dev).await? { info!("{dev} looks initialized"); return Ok(()); } diff --git a/src/cmd/init/networks.rs b/src/cmd/init/networks.rs index 57ccfd3..79e2c28 100644 --- a/src/cmd/init/networks.rs +++ b/src/cmd/init/networks.rs @@ -3,10 +3,10 @@ use log::{info, warn}; use std::collections::BTreeSet as Set; use tokio::process::Command; -use super::{format_err, retry_or_ignore, Result}; +use super::{Result, format_err, retry_or_ignore}; use crate::{ udev, - utils::{select_n_by_regex, select_n_by_udev, NameAliases}, + utils::{NameAliases, select_n_by_regex, select_n_by_udev}, }; use dkl::bootstrap::{Config, Network}; @@ -50,7 +50,7 @@ async fn setup_network(net: &Network, assigned: &mut Set) -> Result<()> "net", "INTERFACE", &udev_filter.clone().into(), - &assigned, + assigned, ) .await? } else { diff --git a/src/cmd/init/sshd.rs b/src/cmd/init/sshd.rs index 854f141..5acba9f 100644 --- a/src/cmd/init/sshd.rs +++ b/src/cmd/init/sshd.rs @@ -1,10 +1,6 @@ use log::{info, warn}; -use std::fs; -use std::io::Write; -use std::os::unix::fs::PermissionsExt; -use std::process::Stdio; -use tokio::net; -use tokio::process::Command; +use std::{fs, io::Write, os::unix::fs::PermissionsExt, process::Stdio}; +use tokio::{net, process::Command}; use super::retry_or_ignore; use dkl::bootstrap::{Config, SSHServer}; @@ -60,7 +56,7 @@ async fn handle_ssh_connections(listener: net::TcpListener, cfg: SSHServer) { } for opt in &options { - sshd_args.extend(["-o", &opt]); + sshd_args.extend(["-o", opt]); } let mut keygen_done = false; diff --git a/src/cmd/init_input.rs b/src/cmd/init_input.rs index 568a596..07ab312 100644 --- a/src/cmd/init_input.rs +++ b/src/cmd/init_input.rs @@ -3,7 +3,7 @@ use crate::input; pub async fn run() { tokio::spawn(async { // give a bit of time for stdout - use tokio::time::{sleep, Duration}; + use tokio::time::{Duration, sleep}; sleep(Duration::from_millis(200)).await; if let Err(e) = input::forward_requests_from_socket().await { diff --git a/src/dklog.rs b/src/dklog.rs index e92c7ac..9c32aaa 100644 --- a/src/dklog.rs +++ b/src/dklog.rs @@ -1,10 +1,9 @@ use std::io::Write; use std::sync::{LazyLock, Mutex}; use std::time::SystemTime; -use tokio::sync::watch; -use tokio::task::JoinSet; +use tokio::{io::AsyncWriteExt, sync::watch, task::JoinSet}; -pub static LOG: LazyLock = LazyLock::new(Log::new); +pub static LOG: LazyLock = LazyLock::new(Log::default); pub fn init() { log::set_logger(&*LOG).expect("set_logger should not fail"); @@ -19,8 +18,8 @@ pub struct Log { tasks: Mutex>>, } -impl Log { - pub fn new() -> Self { +impl Default for Log { + fn default() -> Self { let (tx, rx) = watch::channel(0); Self { start: SystemTime::now(), @@ -30,7 +29,9 @@ impl Log { tasks: Mutex::new(Some(JoinSet::new())), } } +} +impl Log { pub fn spawn(&self, task: impl Future + Send + 'static) { if let Some(tasks) = self.tasks.lock().unwrap().as_mut() { tasks.spawn(task); @@ -47,7 +48,6 @@ impl Log { pub async fn copy_to(&self, mut out: W) { let mut log = self.subscribe(); - use tokio::io::AsyncWriteExt; while let Some(chunk) = log.next().await { let _ = out.write_all(&chunk).await; let _ = out.flush().await; @@ -56,7 +56,8 @@ impl Log { pub async fn close(&self) { self.tx.lock().unwrap().take(); - if let Some(tasks) = self.tasks.lock().unwrap().take() { + let tasks = self.tasks.lock().unwrap().take(); + if let Some(tasks) = tasks { tasks.join_all().await; } } @@ -115,7 +116,7 @@ pub struct LogWatch<'t> { impl<'t> LogWatch<'t> { pub async fn next(&mut self) -> Option> { loop { - let new_pos = self.rx.borrow_and_update().clone(); + let new_pos = *self.rx.borrow_and_update(); if new_pos <= self.pos { if self.rx.changed().await.is_err() { return None; // finished diff --git a/src/input.rs b/src/input.rs index 3c37761..57b0b14 100644 --- a/src/input.rs +++ b/src/input.rs @@ -14,7 +14,7 @@ pub async fn read_password(prompt: impl Display) -> String { } fn choice_char(s: &str) -> char { - s.chars().skip_while(|c| *c != '[').skip(1).next().unwrap() + s.chars().skip_while(|c| *c != '[').nth(1).unwrap() } #[test] @@ -51,7 +51,7 @@ pub async fn read_choice(choices: [&str; N]) -> char { loop { let line = read_line(&prompt).await; - let Some(ch) = line.chars().nth(0) else { + let Some(ch) = line.chars().next() else { continue; }; @@ -70,8 +70,9 @@ pub struct InputRequest { } pub type Reply = Arc>>>; +type RequestSender = watch::Sender>; -static REQ: LazyLock>>> = LazyLock::new(|| { +static REQ: LazyLock> = LazyLock::new(|| { let (tx, _) = watch::channel(None); Mutex::new(tx) }); @@ -117,7 +118,7 @@ pub async fn answer_requests_from_stdin() { if req.hide { match termios::Termios::from_fd(0) { Ok(mut tio) => { - saved_termios = Some(tio.clone()); + saved_termios = Some(tio); tio.c_lflag &= !termios::ECHO; if let Err(e) = termios::tcsetattr(0, termios::TCSAFLUSH, &tio) { warn!("password may be echoed! {e}"); @@ -160,10 +161,10 @@ pub async fn answer_requests_from_stdin() { ); // restore term if input was hidden - if let Some(tio) = saved_termios { - if let Err(e) = termios::tcsetattr(0, termios::TCSAFLUSH, &tio) { - warn!("failed to restore pty attrs: {e}"); - } + if let Some(tio) = saved_termios + && let Err(e) = termios::tcsetattr(0, termios::TCSAFLUSH, &tio) + { + warn!("failed to restore pty attrs: {e}"); } } } diff --git a/src/lvm.rs b/src/lvm.rs index 26f0b86..f0de4c7 100644 --- a/src/lvm.rs +++ b/src/lvm.rs @@ -1,4 +1,4 @@ -use eyre::{Result, format_err}; +use eyre::{format_err, Result}; use tokio::process::Command; #[derive(Debug, serde::Deserialize, serde::Serialize)] @@ -55,7 +55,7 @@ pub struct LV { impl LV { pub fn equal_name(&self, vg_name: &str, lv_name: &str) -> bool { - vg_name == &self.vg_name && lv_name == &self.lv_name + vg_name == self.vg_name && lv_name == self.lv_name } } @@ -90,7 +90,7 @@ async fn report_cmd(cmd: &str, find: fn(ReportObj) -> Option>) -> Resu .await?; if !output.status.success() { - let stderr = String::from_utf8_lossy(&output.stderr.trim_ascii()); + let stderr = String::from_utf8_lossy(output.stderr.trim_ascii()); return Err(format_err!("{cmd} failed: {}", stderr)); } diff --git a/src/udev.rs b/src/udev.rs index 8bc8b7d..9ddbf08 100644 --- a/src/udev.rs +++ b/src/udev.rs @@ -1,6 +1,8 @@ use eyre::Result; use log::warn; +use dkl::bootstrap::UdevFilter; + pub struct Device { sysname: String, output: String, @@ -41,7 +43,7 @@ pub fn get_devices(class: &str) -> Result> { let path = path.to_string_lossy(); let output = std::process::Command::new("udevadm") - .args(&["info", &format!("--path={path}")]) + .args(["info", &format!("--path={path}")]) .stderr(std::process::Stdio::piped()) .output()?; @@ -102,10 +104,7 @@ pub struct Devs { impl<'t> Devs { pub fn iter(&'t self) -> impl Iterator> { - self.data - .split("\n\n") - .filter(|s| !s.is_empty()) - .map(|s| Dev(s)) + self.data.split("\n\n").filter(|s| !s.is_empty()).map(Dev) } pub fn of_subsystem(&'t self, subsystem: &str) -> impl Iterator> { @@ -174,7 +173,7 @@ pub enum Filter { False, } -impl<'t> Filter { +impl Filter { pub fn matches(&self, dev: &Dev) -> bool { match self { Self::False => false, @@ -190,21 +189,22 @@ impl<'t> Filter { } } -impl<'t> Into for dkl::bootstrap::UdevFilter { - fn into(self) -> Filter { - match self { - Self::Has(p) => Filter::Has(p), - Self::Eq(p, v) => Filter::Eq(p, v), - Self::Glob(p, pattern) => match glob::Pattern::new(&pattern) { +impl From for Filter { + fn from(filter: UdevFilter) -> Filter { + use UdevFilter::*; + match filter { + Has(p) => Filter::Has(p), + Eq(p, v) => Filter::Eq(p, v), + Glob(p, pattern) => match glob::Pattern::new(&pattern) { Ok(pattern) => Filter::Glob(p, pattern), Err(e) => { warn!("pattern {pattern:?} will never match: {e}"); Filter::False } }, - Self::And(ops) => Filter::And(ops.into_iter().map(Self::into).collect()), - Self::Or(ops) => Filter::Or(ops.into_iter().map(Self::into).collect()), - Self::Not(op) => Filter::Not(Box::new((*op).into())), + And(ops) => Filter::And(ops.into_iter().map(|op| op.into()).collect()), + Or(ops) => Filter::Or(ops.into_iter().map(|op| op.into()).collect()), + Not(op) => Filter::Not(Box::new((*op).into())), } } } diff --git a/src/utils.rs b/src/utils.rs index d5a837d..bd41a33 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -66,7 +66,7 @@ impl NameAliases { pub fn select_n_by_regex<'t>( n: i16, - regexs: &Vec, + regexs: &[String], nas: impl Iterator, ) -> Vec { // compile regexs @@ -91,7 +91,7 @@ pub fn select_n_by_regex<'t>( } } -pub async fn select_n_by_udev<'t>( +pub async fn select_n_by_udev( n: i16, subsystem: &str, result_property: &str,