Skip to content

Commit f546aa0

Browse files
authored
chore(ci): pin Rust MSRV to 1.94 (#2035)
## Summary Pin Saluki's Rust MSRV to 1.94 and align the Rust toolchain pins used by local development, Cargo metadata, CI images, Docker build defaults, and nightly-only tooling. ## Changes - Set `workspace.package.rust-version = "1.94"` in the root `Cargo.toml`. - Keep `rust-version = "1.94"` in the standalone `lib/saluki-io/fuzz/Cargo.toml`, which cannot inherit from the root workspace. - Pin `rust-toolchain.toml` to `1.94.0`. - Update Rust defaults in CI/build Dockerfiles from `1.93.0`/`stable` to `1.94.0`. - Pin nightly-only tooling to `nightly-2026-01-18`, which reports `rustc 1.94.0-nightly`. - Replace unqualified `cargo +nightly` commands in Makefile, GitLab fuzzing, docs, and the fuzz infrastructure script with the pinned nightly version. - Replace uses of unstable `Atomic*::try_update` with stable `fetch_update` so the workspace builds on Rust 1.94. - Pass an explicit cwd to `cargo sort --workspace` in Makefile fmt targets so formatting checks work from linked worktrees. - Make the `host_exec_times_out` unit test use a Windows-native sleep command so it exercises timeout behavior on Windows CI. - Add retrying cleanup for macOS Datadog Agent DMG mounts in both provisioning and CI before/after hooks for persistent runners. - Bump `crossbeam-epoch` in `Cargo.lock` to `0.9.20` to resolve `RUSTSEC-2026-0204` reported by `cargo-deny` during pre-commit. ## Test plan - `cargo +1.94.0 nextest run -p panoramic actions::target_exec::tests::host_exec_times_out` - `cargo +1.94.0 check --workspace --all-targets` - `make check-fmt` - `make generate-api-docs` - `make check-deny` - `make check-docs` - `python3 -m py_compile ci/tooling/fuzz_infra.py` - `bash -n ci/tooling/cleanup-macos-dda-mounts.sh` - `make -n provision-macos-test-env` - `git diff --check` - Pre-commit hook completed successfully, including fmt, clippy, license check, cargo-deny, Vale, and API docs check. Co-authored-by: travis.thieman <travis.thieman@datadoghq.com>
1 parent b993055 commit f546aa0

19 files changed

Lines changed: 122 additions & 43 deletions

File tree

.github/workflows/docs.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ jobs:
3434
sudo apt-get update
3535
sudo apt-get install -y protobuf-compiler
3636
# `make generate-api-docs` installs and pins the nightly toolchain it needs (see
37-
# RUST_NIGHTLY_VERSION in the Makefile); this step just provides rustup/cargo.
38-
- name: Set up Rust
37+
# RUST_NIGHTLY_VERSION in the Makefile); this step just provides Rust 1.94 and rustup/cargo.
38+
- name: Set up Rust 1.94
3939
uses: actions-rust-lang/setup-rust-toolchain@166cdcfd11aee3cb47222f9ddb555ce30ddb9659 # v1.17
4040
with:
41-
toolchain: stable
41+
toolchain: 1.94.0
4242
cache: false
4343
rustflags: ""
4444
- name: Generate API documentation

.gitlab/e2e.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,9 @@ test-integration:
159159
# $CI_PROJECT_DIR/target/<profile>/, holds UDP 58125 / TCP 5100–5102 etc. across runs).
160160
# Both profiles are swept because BUILD_PROFILE flows from .gitlab-ci.yml workflow
161161
# rules: `release` on dev pipelines, `optimized-release` on tagged release pipelines.
162+
# - stale Datadog Agent DMG mounts from interrupted installs; these runners persist across jobs.
162163
- sudo pkill -9 -f /tmp/saluki-dda/ || true
164+
- bash ci/tooling/cleanup-macos-dda-mounts.sh || true
163165
- sudo pkill -9 -f /target/release/agent-data-plane || true
164166
- sudo pkill -9 -f /target/optimized-release/agent-data-plane || true
165167
script:
@@ -177,6 +179,7 @@ test-integration:
177179
- ps -axo pid,ppid,user,command > integration-logs/host-diag/ps.txt 2>&1 || true
178180
- cp /tmp/saluki-agent-bootstrap.log integration-logs/host-diag/saluki-agent-bootstrap.log 2>/dev/null || true
179181
- ls -la /tmp/saluki-dda/datadog-agent/etc/ > integration-logs/host-diag/sandbox-etc.txt 2>&1 || true
182+
- bash ci/tooling/cleanup-macos-dda-mounts.sh || true
180183

181184
test-integration-macos-arm64:
182185
extends:

.gitlab/fuzz.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ fuzz:infra:
1010
- if: '$CI_COMMIT_REF_NAME == "main" && $CI_PIPELINE_SOURCE == "push"'
1111
- when: manual
1212
allow_failure: true
13+
variables:
14+
RUST_NIGHTLY_VERSION: nightly-2026-01-18
1315
before_script:
14-
- cargo +nightly install cargo-fuzz
16+
- cargo +${RUST_NIGHTLY_VERSION} install cargo-fuzz
1517
# Install Python dependencies for fuzz_infra.py
1618
- apt-get update && apt-get install -y python3 python3-pip
1719
- pip3 install requests toml # parsing of cargo toml files

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ resolver = "2"
4444

4545
[workspace.package]
4646
edition = "2021"
47+
rust-version = "1.94"
4748
license = "Apache-2.0"
4849
repository = "https://github.com/DataDog/saluki"
4950

Makefile

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export GO_APP_IMAGE ?= ubuntu:24.04
5353
# Pinned nightly toolchain shared by the Miri tests and API-doc generation, both of which rely on
5454
# nightly-only features. Keeping it in one variable ensures the two stay in lockstep; bump here to
5555
# move both at once.
56-
export RUST_NIGHTLY_VERSION ?= nightly-2026-07-05
56+
export RUST_NIGHTLY_VERSION ?= nightly-2026-01-18
5757

5858
# Tool configuration.
5959
export AUTOINSTALL ?= true
@@ -525,12 +525,12 @@ check-deny: ## Check all crate dependencies for outstanding advisories or usage
525525
@cargo deny check --hide-inclusion-graph --show-stats
526526

527527
.PHONY: check-fmt
528-
check-fmt: check-rust-build-tools cargo-install-cargo-sort
528+
check-fmt: check-rust-build-tools ensure-rust-nightly cargo-install-cargo-sort
529529
check-fmt: ## Check that all Rust source files are formatted properly
530530
@echo "[*] Checking Rust source code formatting..."
531-
@cargo +nightly fmt -- --check
531+
@cargo +$(RUST_NIGHTLY_VERSION) fmt -- --check
532532
@echo "[*] Checking Cargo.toml formatting..."
533-
@cargo sort --workspace --check >/dev/null
533+
@cargo sort --workspace . --check >/dev/null
534534

535535
.PHONY: check-licenses
536536
check-licenses: check-rust-build-tools cargo-install-dd-rust-license-tool
@@ -697,12 +697,24 @@ provision-macos-test-env: ## Installs the pinned Datadog Agent ($(MACOS_TEST_AGE
697697
curl -fL "$(MACOS_TEST_AGENT_DMG_URL)" -o "$$DMG_PATH"; \
698698
fi; \
699699
MOUNT_DIR=$$(mktemp -d /tmp/saluki-dda-mount-XXXXXX); \
700-
hdiutil attach "$$DMG_PATH" -mountpoint "$$MOUNT_DIR" -nobrowse >/dev/null; \
700+
cleanup_mount() { bash "$(CURDIR)/ci/tooling/cleanup-macos-dda-mounts.sh" "$$MOUNT_DIR"; }; \
701+
trap cleanup_mount EXIT; \
702+
for attempt in 1 2 3; do \
703+
if hdiutil attach "$$DMG_PATH" -mountpoint "$$MOUNT_DIR" -nobrowse >/dev/null; then \
704+
break; \
705+
fi; \
706+
if [ "$$attempt" = "3" ]; then \
707+
echo "ERROR: failed to attach $$DMG_PATH after $$attempt attempts" >&2; \
708+
exit 1; \
709+
fi; \
710+
echo "[*] Failed to attach $$DMG_PATH on attempt $$attempt; retrying..." >&2; \
711+
sleep $$((attempt * 2)); \
712+
done; \
701713
PKG=$$(find "$$MOUNT_DIR" -name '*.pkg' | head -1); \
702714
EXPAND_DIR=$$(mktemp -d /tmp/saluki-dda-expand-XXXXXX) && rm -rf "$$EXPAND_DIR"; \
703715
pkgutil --expand-full "$$PKG" "$$EXPAND_DIR" >/dev/null; \
704-
hdiutil detach "$$MOUNT_DIR" >/dev/null; \
705-
rmdir "$$MOUNT_DIR" 2>/dev/null || true; \
716+
cleanup_mount; \
717+
trap - EXIT; \
706718
PAYLOAD_DIR=$$(find "$$EXPAND_DIR" -type d -name Payload | head -1); \
707719
if [ -z "$$PAYLOAD_DIR" ] || [ ! -x "$$PAYLOAD_DIR/bin/agent/agent" ]; then \
708720
echo "ERROR: pkg payload did not contain bin/agent/agent. Expanded layout:" >&2; \
@@ -755,7 +767,7 @@ ifeq ($(shell command -v rustup >/dev/null || echo not-found), not-found)
755767
$(error "Rustup must be present to install the nightly toolchain: https://www.rust-lang.org/tools/install")
756768
endif
757769
@echo "[*] Installing/updating nightly Rust ($(RUST_NIGHTLY_VERSION))..."
758-
@rustup toolchain install $(RUST_NIGHTLY_VERSION) --profile minimal
770+
@rustup toolchain install $(RUST_NIGHTLY_VERSION) --profile minimal --component rustfmt
759771

760772
.PHONY: ensure-rust-miri
761773
ensure-rust-miri: ensure-rust-nightly
@@ -949,14 +961,14 @@ clean-kind: check-kind-tools ## Cleans up orphaned panoramic namespaces in the k
949961
clean-correctness: clean-airlock clean-kind ## Cleans up all orphaned correctness test resources (Docker + kind)
950962

951963
.PHONY: fmt
952-
fmt: check-rust-build-tools cargo-install-cargo-autoinherit cargo-install-cargo-sort
964+
fmt: check-rust-build-tools ensure-rust-nightly cargo-install-cargo-autoinherit cargo-install-cargo-sort
953965
fmt: ## Format Rust source code
954966
@echo "[*] Formatting Rust source code..."
955-
@cargo +nightly fmt
967+
@cargo +$(RUST_NIGHTLY_VERSION) fmt
956968
@echo "[*] Ensuring workspace dependencies are autoinherited..."
957969
@cargo autoinherit 2>/dev/null
958970
@echo "[*] Formatting Cargo.toml files..."
959-
@cargo sort --workspace >/dev/null
971+
@cargo sort --workspace . >/dev/null
960972

961973
.PHONY: sync-licenses
962974
sync-licenses: check-rust-build-tools cargo-install-dd-rust-license-tool

bin/correctness/panoramic/src/actions/target_exec.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,17 +236,38 @@ mod tests {
236236
assert!(err.to_string().contains("fail-message"));
237237
}
238238

239+
fn slow_host_command() -> Vec<String> {
240+
#[cfg(windows)]
241+
{
242+
vec![
243+
"powershell".to_string(),
244+
"-NoProfile".to_string(),
245+
"-NonInteractive".to_string(),
246+
"-Command".to_string(),
247+
"Start-Sleep -Seconds 5".to_string(),
248+
]
249+
}
250+
251+
#[cfg(not(windows))]
252+
{
253+
vec!["sh".to_string(), "-c".to_string(), "sleep 5".to_string()]
254+
}
255+
}
256+
239257
#[tokio::test]
240258
async fn host_exec_times_out() {
241259
let err = exec_on_host_with_timeout(
242-
&["sh".to_string(), "-c".to_string(), "sleep 5".to_string()],
260+
&slow_host_command(),
243261
std::time::Duration::from_millis(50),
244262
&tokio_util::sync::CancellationToken::new(),
245263
&tokio_util::sync::CancellationToken::new(),
246264
)
247265
.await
248266
.expect_err("host command should time out");
249267

250-
assert!(err.to_string().contains("Timed out running host command"));
268+
assert!(
269+
err.to_string().contains("Timed out running host command"),
270+
"unexpected error: {err}"
271+
);
251272
}
252273
}

ci/images/definitions/build/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ COPY bin/agent-data-plane/Cargo.toml /tmp/bin/agent-data-plane/Cargo.toml
1414

1515
FROM ${BASE_IMAGE}
1616

17-
ARG RUST_VERSION=1.93.0
17+
ARG RUST_VERSION=1.94.0
1818
ARG TARGETARCH
1919

2020
# Base image defaults to the unprivileged `dog` user; switch to root for all install steps.

ci/images/definitions/smp/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ RUN chmod +x /install-buildcache.sh && /install-buildcache.sh
2828
# Final stage: runtime-only dependencies. Build toolchain is not present here.
2929
FROM registry.ddbuild.io/docker:24.0.4-jammy
3030

31-
ARG RUST_VERSION=1.93.0
31+
ARG RUST_VERSION=1.94.0
3232

3333
ENV DEBIAN_FRONTEND=noninteractive \
3434
TZ=Etc/UTC
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#!/usr/bin/env bash
2+
# Cleans up temporary Datadog Agent DMG mount points left by macOS integration-test setup.
3+
set -euo pipefail
4+
5+
retry_detach() {
6+
local mount_dir="$1"
7+
8+
if [[ ! -d "$mount_dir" ]]; then
9+
return 0
10+
fi
11+
12+
if ! mount | grep -F " on ${mount_dir} " >/dev/null 2>&1 && ! hdiutil info | grep -F "$mount_dir" >/dev/null 2>&1; then
13+
rmdir "$mount_dir" 2>/dev/null || true
14+
return 0
15+
fi
16+
17+
local attempt
18+
for attempt in 1 2 3; do
19+
if hdiutil detach "$mount_dir" >/dev/null 2>&1; then
20+
rmdir "$mount_dir" 2>/dev/null || true
21+
return 0
22+
fi
23+
24+
echo "[*] Failed to detach ${mount_dir} on attempt ${attempt}; retrying..." >&2
25+
sleep $((attempt * 2))
26+
done
27+
28+
echo "[*] Forcing detach of ${mount_dir} after retries failed..." >&2
29+
hdiutil detach -force "$mount_dir" >/dev/null 2>&1 || true
30+
rmdir "$mount_dir" 2>/dev/null || true
31+
}
32+
33+
if [[ "$#" -gt 0 ]]; then
34+
for mount_dir in "$@"; do
35+
retry_detach "$mount_dir"
36+
done
37+
else
38+
shopt -s nullglob
39+
for mount_dir in /tmp/saluki-dda-mount-*; do
40+
retry_detach "$mount_dir"
41+
done
42+
fi

ci/tooling/fuzz_infra.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import toml
1515

1616
DEFAULT_FUZZING_SLACK_CHANNEL = "fuzzing-ops"
17+
DEFAULT_RUST_NIGHTLY_VERSION = "nightly-2026-01-18"
1718

1819
# Lets reuse the token for all requests to avoid issues with rate limiting.
1920
# The process should be short lived enough that the token should be valid for the duration (it's only the uploading step)
@@ -143,8 +144,12 @@ def upload_fuzz(
143144
print(response_json)
144145

145146

147+
def get_rust_nightly_version() -> str:
148+
return os.getenv("RUST_NIGHTLY_VERSION", DEFAULT_RUST_NIGHTLY_VERSION)
149+
150+
146151
def search_fuzz_tests(directory) -> list[str]:
147-
fuzz_list_cmd = ["cargo", "+nightly", "fuzz", "list"]
152+
fuzz_list_cmd = ["cargo", f"+{get_rust_nightly_version()}", "fuzz", "list"]
148153
process = Popen(fuzz_list_cmd, cwd=directory, stdout=PIPE, stderr=PIPE)
149154
stdout, stderr = process.communicate()
150155

@@ -162,7 +167,7 @@ def search_fuzz_tests(directory) -> list[str]:
162167

163168

164169
def build_fuzz(directory, fuzz_test) -> bool:
165-
build_cmd = ["cargo", "+nightly", "fuzz", "build", fuzz_test]
170+
build_cmd = ["cargo", f"+{get_rust_nightly_version()}", "fuzz", "build", fuzz_test]
166171
return Popen(build_cmd, cwd=directory).wait() == 0
167172

168173

0 commit comments

Comments
 (0)