From ae0dbf3bd90fcbe1a85ad49f90f2141f850b7a90 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Fri, 6 Jun 2025 22:00:43 +0200 Subject: [PATCH 1/2] chore(deps): lock file maintenance --- Cargo.lock | 16 ++++++++-------- flake.lock | 20 ++++++++++---------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5bdb13b..c1e3874 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -185,9 +185,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" -version = "1.2.25" +version = "1.2.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0fc897dc1e865cc67c0e05a836d9d3f1df3cbe442aa4a9473b18e12624a4951" +checksum = "956a5e21988b87f372569b66183b78babf23ebc2e744b733e4350a752c4dafac" dependencies = [ "shlex", ] @@ -834,9 +834,9 @@ checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" [[package]] name = "smallvec" -version = "1.15.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" @@ -1027,9 +1027,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +checksum = "1b1ffbcf9c6f6b99d386e7444eb608ba646ae452a36b39737deb9663b610f662" dependencies = [ "proc-macro2", "quote", @@ -1038,9 +1038,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ "once_cell", "valuable", diff --git a/flake.lock b/flake.lock index 800b976..5d5b7a2 100644 --- a/flake.lock +++ b/flake.lock @@ -37,11 +37,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1749008870, - "narHash": "sha256-5QEAcgawS2tOJrLr+U5DtzlShSCEpeg7PZDC7txvLQs=", - "rev": "c2a03962b8e24e669fb37b7df10e7c79531ff1a4", + "lastModified": 1749238035, + "narHash": "sha256-+w+VydE8NSQXu8RSNLhn0fVMaEoFPgUbNYa8m1rewuM=", + "rev": "d3d2d80a2191a73d1e86456a751b83aa13085d7d", "type": "tarball", - "url": "https://releases.nixos.org/nixos/unstable/nixos-25.11pre810143.c2a03962b8e2/nixexprs.tar.xz?rev=c2a03962b8e24e669fb37b7df10e7c79531ff1a4" + "url": "https://releases.nixos.org/nixos/unstable/nixos-25.11pre811203.d3d2d80a2191/nixexprs.tar.xz?rev=d3d2d80a2191a73d1e86456a751b83aa13085d7d" }, "original": { "type": "tarball", @@ -65,11 +65,11 @@ ] }, "locked": { - "lastModified": 1749091064, - "narHash": "sha256-TGtYjzRX0sueFhwYsnNNFF5TTKnpnloznpIghLzxeXo=", + "lastModified": 1749177458, + "narHash": "sha256-9HNq3EHZIvvxXQyEn0sYOywcESF1Xqw2Q8J1ZewcXuk=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "12419593ce78f2e8e1e89a373c6515885e218acb", + "rev": "d58933b88cef7a05e9677e94352fd6fedba402cd", "type": "github" }, "original": { @@ -100,11 +100,11 @@ ] }, "locked": { - "lastModified": 1748243702, - "narHash": "sha256-9YzfeN8CB6SzNPyPm2XjRRqSixDopTapaRsnTpXUEY8=", + "lastModified": 1749194973, + "narHash": "sha256-eEy8cuS0mZ2j/r/FE0/LYBSBcIs/MKOIVakwHVuqTfk=", "owner": "numtide", "repo": "treefmt-nix", - "rev": "1f3f7b784643d488ba4bf315638b2b0a4c5fb007", + "rev": "a05be418a1af1198ca0f63facb13c985db4cb3c5", "type": "github" }, "original": { From 74cf34edff10538b74c85df4e35bd4e6de3c2d82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jalil=20David=20Salam=C3=A9=20Messina?= Date: Sat, 7 Jun 2025 00:18:05 +0200 Subject: [PATCH 2/2] fix(clippy): split code a bit Main was too big for clippy --- src/main.rs | 135 ++++++++++++++++++++++++++++------------------------ 1 file changed, 72 insertions(+), 63 deletions(-) diff --git a/src/main.rs b/src/main.rs index bd7aa91..193df24 100644 --- a/src/main.rs +++ b/src/main.rs @@ -128,7 +128,7 @@ impl SavedIPs { .chain(self.ipv6.map(IpAddr::V6)) } - fn from_str(data: &str) -> miette::Result { + fn from_str(data: &str) -> Result { match data.parse::() { // Old format Ok(IpAddr::V4(ipv4)) => Ok(Self { @@ -145,7 +145,7 @@ impl SavedIPs { } impl AppState<'static> { - fn from_args(args: &Opts, config: &config::Config) -> miette::Result { + fn from_args(args: &Opts, config: &config::Config) -> Result { let Opts { verbosity: _, data_dir, @@ -180,7 +180,7 @@ impl AppState<'static> { // Load keyfile key_file: key_file .as_deref() - .map(|path| -> miette::Result<_> { + .map(|path| -> Result<_> { std::fs::File::open(path) .into_diagnostic() .wrap_err_with(|| { @@ -255,6 +255,18 @@ impl std::str::FromStr for Ipv6Prefix { } } +fn load_password(path: &Path) -> Result> { + let pass = std::fs::read_to_string(path).into_diagnostic()?; + + let pass: Box<[u8]> = URL_SAFE_NO_PAD + .decode(pass.trim().as_bytes()) + .into_diagnostic() + .wrap_err_with(|| format!("failed to decode password from {}", path.display()))? + .into(); + + Ok(pass) +} + #[tracing::instrument(err)] fn main() -> Result<()> { // set panic hook to pretty print with miette's formatter @@ -310,18 +322,8 @@ fn main() -> Result<()> { let password_hash = config .password .password_file - .map(|path| -> miette::Result<_> { - let path = path.as_path(); - let pass = std::fs::read_to_string(path).into_diagnostic()?; - - let pass: Box<[u8]> = URL_SAFE_NO_PAD - .decode(pass.trim().as_bytes()) - .into_diagnostic() - .wrap_err_with(|| format!("failed to decode password from {}", path.display()))? - .into(); - - Ok(pass) - }) + .as_deref() + .map(load_password) .transpose() .wrap_err("failed to load password hash")?; @@ -336,63 +338,70 @@ fn main() -> Result<()> { .into_diagnostic() .wrap_err("failed to start the tokio runtime")?; - rt.block_on(async { - // Update DNS record with previous IPs (if available) - let ips = state.last_ips.lock().await.clone(); + rt.block_on(async_main(state, config, password_hash)) + .wrap_err("failed to run main loop") +} - let mut actions = ips - .ips() - .filter(|ip| config.records.ip_type.valid_for_type(*ip)) - .flat_map(|ip| nsupdate::Action::from_records(ip, state.ttl, state.records)) - .peekable(); +#[tracing::instrument(err, skip(state, pass))] +async fn async_main( + state: AppState<'static>, + config: Config, + pass: Option>, +) -> Result<()> { + // Update DNS record with previous IPs (if available) + let ips = state.last_ips.lock().await.clone(); - if actions.peek().is_some() { - match nsupdate::nsupdate(state.key_file, actions).await { - Ok(status) => { - if !status.success() { - error!("nsupdate failed: code {status}"); - bail!("nsupdate returned with code {status}"); - } - } - Err(err) => { - error!("Failed to update records with previous IP: {err}"); - return Err(err) - .into_diagnostic() - .wrap_err("failed to update records with previous IP"); + let mut actions = ips + .ips() + .filter(|ip| config.records.ip_type.valid_for_type(*ip)) + .flat_map(|ip| nsupdate::Action::from_records(ip, state.ttl, state.records)) + .peekable(); + + if actions.peek().is_some() { + match nsupdate::nsupdate(state.key_file, actions).await { + Ok(status) => { + if !status.success() { + error!("nsupdate failed: code {status}"); + bail!("nsupdate returned with code {status}"); } } + Err(err) => { + error!("Failed to update records with previous IP: {err}"); + return Err(err) + .into_diagnostic() + .wrap_err("failed to update records with previous IP"); + } } + } - // Create services - let app = Router::new().route("/update", get(update_records)); - // if a password is provided, validate it - let app = if let Some(pass) = password_hash { - app.layer(auth::layer( - Box::leak(pass), - Box::leak(config.password.salt), - )) - } else { - app - } - .layer(config.records.ip_source.into_extension()) - .with_state(state); + // Create services + let app = Router::new().route("/update", get(update_records)); + // if a password is provided, validate it + let app = if let Some(pass) = pass { + app.layer(auth::layer( + Box::leak(pass), + Box::leak(config.password.salt), + )) + } else { + app + } + .layer(config.records.ip_source.into_extension()) + .with_state(state); - let config::Server { address } = config.server; + let config::Server { address } = config.server; - // Start services - info!("starting listener on {address}"); - let listener = tokio::net::TcpListener::bind(address) - .await - .into_diagnostic()?; - info!("listening on {address}"); - axum::serve( - listener, - app.into_make_service_with_connect_info::(), - ) + // Start services + info!("starting listener on {address}"); + let listener = tokio::net::TcpListener::bind(address) .await - .into_diagnostic() - }) - .wrap_err("failed to run main loop") + .into_diagnostic()?; + info!("listening on {address}"); + axum::serve( + listener, + app.into_make_service_with_connect_info::(), + ) + .await + .into_diagnostic() } /// Serde deserialization decorator to map empty Strings to None,