Skip to content

Commit a69dd5c

Browse files
[rust] - Extending the feature support for non-debian platforms. (#1376)
* [rust] - Extending the feature support for non-debian platforms. * Removing unused variables. * corrections done based on review comments. --------- Co-authored-by: Álvaro Rausell Guiard <[email protected]>
1 parent 2e1d523 commit a69dd5c

11 files changed

+399
-28
lines changed

src/rust/README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,12 @@ Installs Rust, common Rust utilities, and their required dependencies
3131

3232
## OS Support
3333

34-
This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed.
34+
This Feature should work on recent versions of Debian/Ubuntu, RedHat Enterprise Linux, Fedora, Alma, RockyLinux
35+
and Mariner distributions with the `apt`, `yum`, `dnf`, `microdnf` and `tdnf` package manager installed.
36+
37+
38+
**Note:** Alpine is not supported because the rustup-init binary requires glibc to run, but Alpine Linux does not include `glibc`
39+
by default. Instead, it uses musl libc, which is not binary-compatible with glibc.
3540

3641
`bash` is required to execute the `install.sh` script.
3742

src/rust/devcontainer-feature.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"id": "rust",
3-
"version": "1.3.3",
3+
"version": "1.4.0",
44
"name": "Rust",
55
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/rust",
66
"description": "Installs Rust, common Rust utilities, and their required dependencies",

src/rust/install.sh

Lines changed: 216 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,77 @@ UPDATE_RUST="${UPDATE_RUST:-"false"}"
1919

2020
set -e
2121

22-
# Clean up
23-
if [ "$(ls -1 /var/lib/apt/lists/ | wc -l)" -gt -1 ]; then
24-
rm -rf /var/lib/apt/lists/*
22+
# Detect the Linux distribution and package manager
23+
PKG_MANAGER=""
24+
25+
# Bring in ID, ID_LIKE, VERSION_ID, VERSION_CODENAME
26+
. /etc/os-release
27+
# Get an adjusted ID independent of distro variants
28+
if [ "${ID}" = "debian" ] || [ "${ID_LIKE}" = "debian" ]; then
29+
ADJUSTED_ID="debian"
30+
elif [ "${ID}" = "alpine" ]; then
31+
ADJUSTED_ID="alpine"
32+
elif [[ "${ID}" = "rhel" || "${ID}" = "fedora" || "${ID}" = "mariner" || "${ID_LIKE}" = *"rhel"* || "${ID_LIKE}" = *"fedora"* || "${ID_LIKE}" = *"mariner"* ]]; then
33+
ADJUSTED_ID="rhel"
34+
VERSION_CODENAME="${ID}${VERSION_ID}"
35+
else
36+
echo "Linux distro ${ID} not supported."
37+
exit 1
38+
fi
39+
40+
if [ "${ADJUSTED_ID}" = "rhel" ] && [ "${VERSION_CODENAME-}" = "centos7" ]; then
41+
# As of 1 July 2024, mirrorlist.centos.org no longer exists.
42+
# Update the repo files to reference vault.centos.org.
43+
sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo
44+
sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo
45+
sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo
46+
fi
47+
48+
49+
# Detect package manager
50+
if command -v apt-get >/dev/null 2>&1; then
51+
PKG_MANAGER="apt"
52+
elif command -v dnf >/dev/null 2>&1; then
53+
PKG_MANAGER="dnf"
54+
elif command -v yum >/dev/null 2>&1; then
55+
PKG_MANAGER="yum"
56+
elif command -v microdnf >/dev/null 2>&1; then
57+
PKG_MANAGER="microdnf"
58+
elif command -v tdnf >/dev/null 2>&1; then
59+
PKG_MANAGER="tdnf"
60+
else
61+
echo "No supported package manager found. Supported: apt, dnf, yum, microdnf, tdnf"
62+
exit 1
2563
fi
2664

65+
echo "Detected package manager: $PKG_MANAGER"
66+
67+
# Clean up based on package manager
68+
clean_package_cache() {
69+
case "$PKG_MANAGER" in
70+
apt)
71+
if [ "$(ls -1 /var/lib/apt/lists/ 2>/dev/null | wc -l)" -gt 0 ]; then
72+
rm -rf /var/lib/apt/lists/*
73+
fi
74+
;;
75+
dnf|yum|microdnf)
76+
if command -v dnf >/dev/null 2>&1; then
77+
dnf clean all
78+
elif command -v yum >/dev/null 2>&1; then
79+
yum clean all
80+
elif command -v microdnf >/dev/null 2>&1; then
81+
microdnf clean all
82+
fi
83+
;;
84+
tdnf)
85+
tdnf clean all
86+
;;
87+
esac
88+
}
89+
90+
# Initial cleanup
91+
clean_package_cache
92+
2793
if [ "$(id -u)" -ne 0 ]; then
2894
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
2995
exit 1
@@ -106,48 +172,174 @@ check_nightly_version_formatting() {
106172

107173
updaterc() {
108174
if [ "${UPDATE_RC}" = "true" ]; then
109-
echo "Updating /etc/bash.bashrc and /etc/zsh/zshrc..."
110-
if [[ "$(cat /etc/bash.bashrc)" != *"$1"* ]]; then
111-
echo -e "$1" >> /etc/bash.bashrc
175+
echo "Updating shell configuration files..."
176+
local bashrc_file="/etc/bash.bashrc"
177+
178+
# Different distributions use different bashrc locations
179+
if [ ! -f "$bashrc_file" ]; then
180+
if [ -f "/etc/bashrc" ]; then
181+
bashrc_file="/etc/bashrc"
182+
elif [ -f "/etc/bash/bashrc" ]; then
183+
bashrc_file="/etc/bash/bashrc"
184+
fi
185+
fi
186+
187+
if [ -f "$bashrc_file" ] && [[ "$(cat "$bashrc_file")" != *"$1"* ]]; then
188+
echo -e "$1" >> "$bashrc_file"
112189
fi
190+
113191
if [ -f "/etc/zsh/zshrc" ] && [[ "$(cat /etc/zsh/zshrc)" != *"$1"* ]]; then
114192
echo -e "$1" >> /etc/zsh/zshrc
115193
fi
116194
fi
117195
}
118196

119-
apt_get_update()
120-
{
121-
if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then
122-
echo "Running apt-get update..."
123-
apt-get update -y
124-
fi
197+
# Package update functions
198+
pkg_mgr_update() {
199+
case "$PKG_MANAGER" in
200+
apt)
201+
if [ "$(find /var/lib/apt/lists/* 2>/dev/null | wc -l)" = "0" ]; then
202+
echo "Running apt-get update..."
203+
apt-get update -y
204+
fi
205+
;;
206+
dnf)
207+
dnf check-update || true
208+
;;
209+
yum)
210+
yum check-update || true
211+
;;
212+
microdnf)
213+
# microdnf doesn't have check-update
214+
true
215+
;;
216+
tdnf)
217+
tdnf makecache || true
218+
;;
219+
esac
220+
}
221+
222+
# Check if package is installed
223+
is_package_installed() {
224+
local package=$1
225+
case "$PKG_MANAGER" in
226+
apt)
227+
dpkg -s "$package" >/dev/null 2>&1
228+
;;
229+
dnf|yum|microdnf|tdnf)
230+
rpm -q "$package" >/dev/null 2>&1
231+
;;
232+
esac
125233
}
126234

127-
# Checks if packages are installed and installs them if not
235+
# Unified package checking and installation function
128236
check_packages() {
129-
if ! dpkg -s "$@" >/dev/null 2>&1; then
130-
apt_get_update
131-
apt-get -y install --no-install-recommends "$@"
237+
local packages=("$@")
238+
local missing_packages=()
239+
240+
# Check if curl-minimal is installed and swap it with curl
241+
if is_package_installed "curl-minimal"; then
242+
echo "curl-minimal is installed. Swapping it with curl..."
243+
case "$PKG_MANAGER" in
244+
dnf|yum|microdnf)
245+
${PKG_MANAGER} swap curl-minimal curl -y
246+
;;
247+
tdnf)
248+
tdnf remove -y curl-minimal
249+
tdnf install -y curl
250+
;;
251+
*)
252+
echo "Package manager does not support swapping curl-minimal with curl. Please handle this manually."
253+
;;
254+
esac
255+
fi
256+
257+
# Map package names based on distribution
258+
for i in "${!packages[@]}"; do
259+
case "$PKG_MANAGER" in
260+
dnf|yum|microdnf|tdnf)
261+
case "${packages[$i]}" in
262+
"libc6-dev") packages[$i]="glibc-devel" ;;
263+
"python3-minimal") packages[$i]="python3" ;;
264+
"libpython3.*") packages[$i]="python3-devel" ;;
265+
"gnupg2") packages[$i]="gnupg" ;;
266+
esac
267+
;;
268+
esac
269+
done
270+
271+
# Check which packages are missing
272+
for package in "${packages[@]}"; do
273+
if [ -n "$package" ] && ! is_package_installed "$package"; then
274+
missing_packages+=("$package")
275+
fi
276+
done
277+
278+
# Install missing packages
279+
if [ ${#missing_packages[@]} -gt 0 ]; then
280+
pkg_mgr_update
281+
case "$PKG_MANAGER" in
282+
apt)
283+
apt-get -y install --no-install-recommends "${missing_packages[@]}"
284+
;;
285+
dnf)
286+
dnf install -y "${missing_packages[@]}"
287+
;;
288+
yum)
289+
yum install -y "${missing_packages[@]}"
290+
;;
291+
microdnf)
292+
microdnf install -y "${missing_packages[@]}"
293+
;;
294+
tdnf)
295+
tdnf install -y "${missing_packages[@]}"
296+
;;
297+
esac
132298
fi
133299
}
134300

135301
export DEBIAN_FRONTEND=noninteractive
136302

137303
# Install curl, lldb, python3-minimal,libpython and rust dependencies if missing
138-
if ! dpkg -s curl ca-certificates gnupg2 lldb python3-minimal gcc libc6-dev > /dev/null 2>&1; then
139-
apt_get_update
140-
apt-get -y install --no-install-recommends curl ca-certificates gcc libc6-dev
141-
apt-get -y install lldb python3-minimal libpython3.?
304+
echo "Installing required dependencies..."
305+
check_packages curl ca-certificates gcc libc6-dev gnupg2 git
306+
307+
# Install optional dependencies (continue if they fail)
308+
case "$PKG_MANAGER" in
309+
apt)
310+
check_packages lldb python3-minimal libpython3.? || true
311+
;;
312+
dnf|yum|microdnf)
313+
check_packages lldb python3 python3-devel || true
314+
;;
315+
tdnf)
316+
check_packages python3 python3-devel || true
317+
# LLDB might not be available in Photon/Mariner
318+
;;
319+
esac
320+
321+
# Get architecture
322+
if command -v dpkg >/dev/null 2>&1; then
323+
architecture="$(dpkg --print-architecture)"
324+
else
325+
architecture="$(uname -m)"
326+
# Convert common architectures to Debian equivalents
327+
case ${architecture} in
328+
x86_64)
329+
architecture="amd64"
330+
;;
331+
aarch64)
332+
architecture="arm64"
333+
;;
334+
esac
142335
fi
143336

144-
architecture="$(dpkg --print-architecture)"
145337
download_architecture="${architecture}"
146338
case ${download_architecture} in
147-
amd64)
339+
amd64|x86_64)
148340
download_architecture="x86_64"
149341
;;
150-
arm64)
342+
arm64|aarch64)
151343
download_architecture="aarch64"
152344
;;
153345
*) echo "(!) Architecture ${architecture} not supported."
@@ -225,7 +417,6 @@ EOF
225417
chmod -R g+r+w "${RUSTUP_HOME}" "${CARGO_HOME}"
226418

227419
# Clean up
228-
rm -rf /var/lib/apt/lists/*
420+
clean_package_cache
229421

230422
echo "Done!"
231-

test/rust/rust_with_almalinux_8.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
# Optional: Import test library
6+
source dev-container-features-test-lib
7+
8+
# Definition specific tests
9+
check "cargo version" cargo --version
10+
check "rustc version" rustc --version
11+
check "correct rust version" rustup target list | grep aarch64-unknown-linux-gnu
12+
13+
14+
# Report result
15+
reportResults
16+

test/rust/rust_with_almalinux_9.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
# Optional: Import test library
6+
source dev-container-features-test-lib
7+
8+
# Definition specific tests
9+
check "cargo version" cargo --version
10+
check "rustc version" rustc --version
11+
check "correct rust version" rustup target list | grep aarch64-unknown-linux-gnu
12+
13+
14+
# Report result
15+
reportResults
16+

test/rust/rust_with_centos.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
# Optional: Import test library
6+
source dev-container-features-test-lib
7+
8+
# Definition specific tests
9+
check "cargo version" cargo --version
10+
check "rustc version" rustc --version
11+
check "correct rust version" rustup target list | grep aarch64-unknown-linux-gnu
12+
13+
14+
# Report result
15+
reportResults
16+

test/rust/rust_with_fedora.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
# Optional: Import test library
6+
source dev-container-features-test-lib
7+
8+
# Definition specific tests
9+
check "cargo version" cargo --version
10+
check "rustc version" rustc --version
11+
check "correct rust version" rustup target list | grep aarch64-unknown-linux-gnu
12+
13+
14+
# Report result
15+
reportResults
16+

test/rust/rust_with_mariner.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
# Optional: Import test library
6+
source dev-container-features-test-lib
7+
8+
# Definition specific tests
9+
check "cargo version" cargo --version
10+
check "rustc version" rustc --version
11+
check "correct rust version" rustup target list | grep aarch64-unknown-linux-gnu
12+
13+
14+
# Report result
15+
reportResults
16+

0 commit comments

Comments
 (0)