Repository: metalbear-co/mirrord (language: rust)

Issue:
Update deps for operator
For https://github.com/metalbear-co/operator/issues/708


Discussion / hints:
<p><a href="https://linear.app/metalbear/issue/MBE-572/update-deps-for-operator">MBE-572 Update deps for operator</a></p>

Fix patch:
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 1cf7597a86f..818a39e3a89 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -512,3 +512,27 @@ If you're using rust-analyzer VSCode extension, put this block in `.vscode/setti
     ]
 }
 ```
+
+You can use `cargo-zigbuild` to run `cargo check` or `clippy` on the agent's code on macOS.
+
+`cargo check`
+
+```shell
+cargo-zigbuild check -p mirrord-agent --target x86_64-unknown-linux-gnu
+```
+
+`clippy` only for the agent
+
+```shell
+cargo-zigbuild clippy --target x86_64-unknown-linux-gnu -p mirrord-agent -- -Wclippy::indexing_slicing -D warnings
+```
+
+`clippy` for all code:
+
+```shell
+cargo-zigbuild clippy --lib --bins --all-features --target x86_64-unknown-linux-gnu --tests -- -Wclippy::indexing_slicing -D warnings
+```
+
+If it doesn't work, try updating `cargo-zigbuild`
+(`cargo install cargo-zigbuild` or maybe `cargo install cargo-zigbuild --force`)
+or via `homebrew` if it was installed via homebrew.
diff --git a/Cargo.lock b/Cargo.lock
index 0b3aada356e..09852a8212b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -500,6 +500,17 @@ dependencies = [
  "pin-project-lite",
 ]
 
+[[package]]
+name = "async-recursion"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.90",
+]
+
 [[package]]
 name = "async-socks5"
 version = "0.6.0"
@@ -1671,6 +1682,15 @@ dependencies = [
  "cfg-if",
 ]
 
+[[package]]
+name = "crossbeam-channel"
+version = "0.5.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2"
+dependencies = [
+ "crossbeam-utils",
+]
+
 [[package]]
 name = "crossbeam-deque"
 version = "0.8.5"
@@ -2843,10 +2863,11 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
 
 [[package]]
 name = "hickory-proto"
-version = "0.24.1"
+version = "0.25.0-alpha.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07698b8420e2f0d6447a436ba999ec85d8fbf2a398bbd737b82cac4a2e96e512"
+checksum = "d063c0692ee669aa6d261988aa19ca5510f1cc40e4f211024f50c888499a35d7"
 dependencies = [
+ "async-recursion",
  "async-trait",
  "cfg-if",
  "data-encoding",
@@ -2854,12 +2875,12 @@ dependencies = [
  "futures-channel",
  "futures-io",
  "futures-util",
- "idna 0.4.0",
+ "idna",
  "ipnet",
  "once_cell",
  "rand",
  "serde",
- "thiserror 1.0.69",
+ "thiserror 2.0.4",
  "tinyvec",
  "tokio",
  "tracing",
@@ -2868,22 +2889,22 @@ dependencies = [
 
 [[package]]
 name = "hickory-resolver"
-version = "0.24.1"
+version = "0.25.0-alpha.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28757f23aa75c98f254cf0405e6d8c25b831b32921b050a66692427679b1f243"
+checksum = "42bc352e4412fb657e795f79b4efcf2bd60b59ee5ca0187f3554194cd1107a27"
 dependencies = [
  "cfg-if",
  "futures-util",
  "hickory-proto",
  "ipconfig",
- "lru-cache",
+ "moka",
  "once_cell",
  "parking_lot",
  "rand",
  "resolv-conf",
  "serde",
  "smallvec",
- "thiserror 1.0.69",
+ "thiserror 2.0.4",
  "tokio",
  "tracing",
 ]
@@ -3350,16 +3371,6 @@ version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
 
-[[package]]
-name = "idna"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
-dependencies = [
- "unicode-bidi",
- "unicode-normalization",
-]
-
 [[package]]
 name = "idna"
 version = "1.0.3"
@@ -3872,12 +3883,6 @@ dependencies = [
  "redox_syscall",
 ]
 
-[[package]]
-name = "linked-hash-map"
-version = "0.5.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
-
 [[package]]
 name = "linux-raw-sys"
 version = "0.4.14"
@@ -3939,15 +3944,6 @@ version = "0.4.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
 
-[[package]]
-name = "lru-cache"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c"
-dependencies = [
- "linked-hash-map",
-]
-
 [[package]]
 name = "lzma-sys"
 version = "0.1.20"
@@ -4512,6 +4508,7 @@ dependencies = [
  "bincode",
  "bytes",
  "fancy-regex",
+ "hickory-proto",
  "hickory-resolver",
  "http-body-util",
  "http-serde",
@@ -4586,6 +4583,26 @@ dependencies = [
  "syn 2.0.90",
 ]
 
+[[package]]
+name = "moka"
+version = "0.12.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32cf62eb4dd975d2dde76432fb1075c49e3ee2331cf36f1f8fd4b66550d32b6f"
+dependencies = [
+ "crossbeam-channel",
+ "crossbeam-epoch",
+ "crossbeam-utils",
+ "once_cell",
+ "parking_lot",
+ "quanta",
+ "rustc_version",
+ "smallvec",
+ "tagptr",
+ "thiserror 1.0.69",
+ "triomphe",
+ "uuid",
+]
+
 [[package]]
 name = "multimap"
 version = "0.10.0"
@@ -5497,6 +5514,21 @@ dependencies = [
  "prost",
 ]
 
+[[package]]
+name = "quanta"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5"
+dependencies = [
+ "crossbeam-utils",
+ "libc",
+ "once_cell",
+ "raw-cpuid",
+ "wasi",
+ "web-sys",
+ "winapi",
+]
+
 [[package]]
 name = "quick-error"
 version = "1.2.3"
@@ -5647,6 +5679,15 @@ dependencies = [
  "uuid",
 ]
 
+[[package]]
+name = "raw-cpuid"
+version = "11.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ab240315c661615f2ee9f0f2cd32d5a7343a84d5ebcccb99d46e6637565e7b0"
+dependencies = [
+ "bitflags 2.6.0",
+]
+
 [[package]]
 name = "rawsocket"
 version = "0.1.0"
@@ -6816,6 +6857,12 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "tagptr"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417"
+
 [[package]]
 name = "tap"
 version = "1.0.1"
@@ -7421,6 +7468,12 @@ dependencies = [
  "tracing-serde",
 ]
 
+[[package]]
+name = "triomphe"
+version = "0.1.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3"
+
 [[package]]
 name = "try-lock"
 version = "0.2.5"
@@ -7584,12 +7637,6 @@ dependencies = [
  "unic-common",
 ]
 
-[[package]]
-name = "unicode-bidi"
-version = "0.3.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893"
-
 [[package]]
 name = "unicode-ident"
 version = "1.0.14"
@@ -7602,15 +7649,6 @@ version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
 
-[[package]]
-name = "unicode-normalization"
-version = "0.1.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956"
-dependencies = [
- "tinyvec",
-]
-
 [[package]]
 name = "unicode-width"
 version = "0.1.14"
@@ -7663,7 +7701,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60"
 dependencies = [
  "form_urlencoded",
- "idna 1.0.3",
+ "idna",
  "percent-encoding",
  "serde",
 ]
diff --git a/Cargo.toml b/Cargo.toml
index 38f93073108..670566a1e62 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -89,10 +89,11 @@ kube = { git = "https://github.com/kube-rs/kube.git", rev = "ecbdafc214538aadc78
     "socks5",
     "http-proxy",
 ] }
-hickory-resolver = { version = "0.24", features = [
-    "serde-config",
+hickory-resolver = { version = "0.25.0-alpha.4", features = [
+    "serde",
     "tokio-runtime",
 ] }
+hickory-proto = "0.25.0-alpha.4"
 tokio-util = { version = "0.7", features = ["net", "codec"] }
 
 # Used by `layer`, `intproxy`, `tests`, `medschool`, `cli`, `agent`, `operator`.
diff --git a/changelog.d/+update-deps.internal.md b/changelog.d/+update-deps.internal.md
new file mode 100644
index 00000000000..69d615423d4
--- /dev/null
+++ b/changelog.d/+update-deps.internal.md
@@ -0,0 +1,1 @@
+Update hickory dependency version.
diff --git a/mirrord/agent/src/dns.rs b/mirrord/agent/src/dns.rs
index 80ae78b893a..0ad44c76934 100644
--- a/mirrord/agent/src/dns.rs
+++ b/mirrord/agent/src/dns.rs
@@ -1,7 +1,7 @@
 use std::{future, path::PathBuf, time::Duration};
 
 use futures::{stream::FuturesOrdered, StreamExt};
-use hickory_resolver::{system_conf::parse_resolv_conf, AsyncResolver, Hosts};
+use hickory_resolver::{system_conf::parse_resolv_conf, Hosts, Resolver};
 use mirrord_protocol::{
     dns::{DnsLookup, GetAddrInfoRequest, GetAddrInfoResponse},
     DnsLookupError, RemoteResult, ResolveErrorKindInternal, ResponseError,
@@ -69,13 +69,13 @@ impl DnsWorker {
         }
     }
 
-    /// Reads `/etc/resolv.conf` and `/etc/hosts` files, then uses [`AsyncResolver`] to resolve
-    /// address of the given `host`.
+    /// Reads `/etc/resolv.conf` and `/etc/hosts` files, then uses [`hickory_resolver::Resolver`] to
+    /// resolve address of the given `host`.
     ///
     /// # TODO
     ///
     /// We could probably cache results here.
-    /// We cannot cache the [`AsyncResolver`] itself, becaues the configuration in `etc` may change.
+    /// We cannot cache the [`Resolver`] itself, becaues the configuration in `etc` may change.
     #[tracing::instrument(level = Level::TRACE, ret, err(level = Level::TRACE))]
     async fn do_lookup(
         etc_path: PathBuf,
@@ -83,7 +83,7 @@ impl DnsWorker {
         attempts: usize,
         timeout: Duration,
     ) -> RemoteResult<DnsLookup> {
-        // Prepares the `AsyncResolver` after reading some `/etc` DNS files.
+        // Prepares the `Resolver` after reading some `/etc` DNS files.
         //
         // We care about logging these errors, at an `error!` level.
         let resolver: Result<_, ResponseError> = try {
@@ -100,9 +100,10 @@ impl DnsWorker {
             options.attempts = attempts;
             options.ip_strategy = hickory_resolver::config::LookupIpStrategy::Ipv4Only;
 
-            let mut resolver = AsyncResolver::tokio(config, options);
+            let mut resolver = Resolver::tokio(config, options);
 
-            let hosts = Hosts::default().read_hosts_conf(hosts_conf.as_slice())?;
+            let mut hosts = Hosts::default();
+            hosts.read_hosts_conf(hosts_conf.as_slice())?;
             resolver.set_hosts(Some(hosts));
 
             resolver
diff --git a/mirrord/protocol/Cargo.toml b/mirrord/protocol/Cargo.toml
index 5cd94d5961e..1a36c251030 100644
--- a/mirrord/protocol/Cargo.toml
+++ b/mirrord/protocol/Cargo.toml
@@ -21,6 +21,7 @@ actix-codec.workspace = true
 bytes.workspace = true
 thiserror.workspace = true
 hickory-resolver.workspace = true
+hickory-proto.workspace = true
 serde.workspace = true
 bincode.workspace = true
 tracing.workspace = true
diff --git a/mirrord/protocol/src/dns.rs b/mirrord/protocol/src/dns.rs
index e9f5bd368b3..855f52b8af5 100644
--- a/mirrord/protocol/src/dns.rs
+++ b/mirrord/protocol/src/dns.rs
@@ -28,12 +28,10 @@ impl From<LookupIp> for DnsLookup {
                     name_labels, rdata, ..
                 } = record.into_parts();
 
-                rdata
-                    .and_then(|rdata| rdata.ip_addr())
-                    .map(|ip| LookupRecord {
-                        name: name_labels.to_string(),
-                        ip,
-                    })
+                rdata.ip_addr().map(|ip| LookupRecord {
+                    name: name_labels.to_string(),
+                    ip,
+                })
             })
             .collect::<Vec<_>>();
 
diff --git a/mirrord/protocol/src/error.rs b/mirrord/protocol/src/error.rs
index 8ac96522537..20ac38a149d 100644
--- a/mirrord/protocol/src/error.rs
+++ b/mirrord/protocol/src/error.rs
@@ -7,7 +7,8 @@ use std::{
 };
 
 use bincode::{Decode, Encode};
-use hickory_resolver::error::{ResolveError, ResolveErrorKind};
+use hickory_proto::ProtoErrorKind;
+use hickory_resolver::{ResolveError, ResolveErrorKind};
 use semver::VersionReq;
 use thiserror::Error;
 use tracing::warn;
@@ -181,12 +182,9 @@ impl From<io::Error> for ResponseError {
 
 impl From<ResolveError> for ResponseError {
     fn from(fail: ResolveError) -> Self {
-        match fail.kind().to_owned() {
-            ResolveErrorKind::Io(io_fail) => io_fail.into(),
-            other => Self::DnsLookup(DnsLookupError {
-                kind: From::from(other),
-            }),
-        }
+        Self::DnsLookup(DnsLookupError {
+            kind: From::from(fail.kind().to_owned()),
+        })
     }
 }
 /// Alternative to `std::io::ErrorKind`, used to implement `bincode::Encode` and `bincode::Decode`.
@@ -330,19 +328,21 @@ impl From<ResolveErrorKind> for ResolveErrorKindInternal {
                 ResolveErrorKindInternal::Message(message.to_string())
             }
             ResolveErrorKind::Msg(message) => ResolveErrorKindInternal::Message(message),
-            ResolveErrorKind::NoConnections => ResolveErrorKindInternal::NoConnections,
-            ResolveErrorKind::NoRecordsFound { response_code, .. } => {
-                ResolveErrorKindInternal::NoRecordsFound(response_code.into())
-            }
-            ResolveErrorKind::Proto(_) => ResolveErrorKindInternal::Proto,
-            ResolveErrorKind::Timeout => ResolveErrorKindInternal::Timeout,
-            ResolveErrorKind::Io(fail) => match fail.kind() {
-                io::ErrorKind::NotFound => ResolveErrorKindInternal::NotFound,
-                io::ErrorKind::PermissionDenied => ResolveErrorKindInternal::PermissionDenied,
-                other => {
-                    warn!(?other, "unknown IO error");
-                    ResolveErrorKindInternal::Unknown
+            ResolveErrorKind::Proto(proto_error) => match *proto_error.kind {
+                ProtoErrorKind::NoConnections => ResolveErrorKindInternal::NoConnections,
+                ProtoErrorKind::NoRecordsFound { response_code, .. } => {
+                    ResolveErrorKindInternal::NoRecordsFound(response_code.into())
                 }
+                ProtoErrorKind::Timeout => ResolveErrorKindInternal::Timeout,
+                ProtoErrorKind::Io(fail) => match fail.kind() {
+                    io::ErrorKind::NotFound => ResolveErrorKindInternal::NotFound,
+                    io::ErrorKind::PermissionDenied => ResolveErrorKindInternal::PermissionDenied,
+                    other => {
+                        warn!(?other, "unknown IO error");
+                        ResolveErrorKindInternal::Unknown
+                    }
+                },
+                _ => ResolveErrorKindInternal::Proto,
             },
             _ => {
                 warn!(?error_kind, "unknown error kind");


Test patch: