Skip to content

Commit 0403633

Browse files
committed
[rust] - Extending the feature support for non-debian platforms.
1 parent 66c73df commit 0403633

11 files changed

Lines changed: 399 additions & 28 deletions

src/rust/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ 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+
Alpine is not supported because the rustup-init binary requires glibc to run, but Alpine Linux does not include `glibc`
37+
by default. Instead, it uses musl libc, which is not binary-compatible with glibc.
3538

3639
`bash` is required to execute the `install.sh` script.
3740

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.3.4",
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: 218 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,79 @@ 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+
DISTRO=""
24+
DISTRO_FAMILY=""
25+
PKG_MANAGER=""
26+
27+
# Bring in ID, ID_LIKE, VERSION_ID, VERSION_CODENAME
28+
. /etc/os-release
29+
# Get an adjusted ID independent of distro variants
30+
if [ "${ID}" = "debian" ] || [ "${ID_LIKE}" = "debian" ]; then
31+
ADJUSTED_ID="debian"
32+
elif [ "${ID}" = "alpine" ]; then
33+
ADJUSTED_ID="alpine"
34+
elif [[ "${ID}" = "rhel" || "${ID}" = "fedora" || "${ID}" = "mariner" || "${ID_LIKE}" = *"rhel"* || "${ID_LIKE}" = *"fedora"* || "${ID_LIKE}" = *"mariner"* ]]; then
35+
ADJUSTED_ID="rhel"
36+
VERSION_CODENAME="${ID}${VERSION_ID}"
37+
else
38+
echo "Linux distro ${ID} not supported."
39+
exit 1
40+
fi
41+
42+
if [ "${ADJUSTED_ID}" = "rhel" ] && [ "${VERSION_CODENAME-}" = "centos7" ]; then
43+
# As of 1 July 2024, mirrorlist.centos.org no longer exists.
44+
# Update the repo files to reference vault.centos.org.
45+
sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo
46+
sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo
47+
sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo
48+
fi
49+
50+
51+
# Detect package manager
52+
if command -v apt-get >/dev/null 2>&1; then
53+
PKG_MANAGER="apt"
54+
elif command -v dnf >/dev/null 2>&1; then
55+
PKG_MANAGER="dnf"
56+
elif command -v yum >/dev/null 2>&1; then
57+
PKG_MANAGER="yum"
58+
elif command -v microdnf >/dev/null 2>&1; then
59+
PKG_MANAGER="microdnf"
60+
elif command -v tdnf >/dev/null 2>&1; then
61+
PKG_MANAGER="tdnf"
62+
else
63+
echo "No supported package manager found. Supported: apt, dnf, yum, microdnf, tdnf"
64+
exit 1
2565
fi
2666

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

107175
updaterc() {
108176
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
177+
echo "Updating shell configuration files..."
178+
local bashrc_file="/etc/bash.bashrc"
179+
180+
# Different distributions use different bashrc locations
181+
if [ ! -f "$bashrc_file" ]; then
182+
if [ -f "/etc/bashrc" ]; then
183+
bashrc_file="/etc/bashrc"
184+
elif [ -f "/etc/bash/bashrc" ]; then
185+
bashrc_file="/etc/bash/bashrc"
186+
fi
187+
fi
188+
189+
if [ -f "$bashrc_file" ] && [[ "$(cat "$bashrc_file")" != *"$1"* ]]; then
190+
echo -e "$1" >> "$bashrc_file"
112191
fi
192+
113193
if [ -f "/etc/zsh/zshrc" ] && [[ "$(cat /etc/zsh/zshrc)" != *"$1"* ]]; then
114194
echo -e "$1" >> /etc/zsh/zshrc
115195
fi
116196
fi
117197
}
118198

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

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

135303
export DEBIAN_FRONTEND=noninteractive
136304

137305
# 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.?
306+
echo "Installing required dependencies..."
307+
check_packages curl ca-certificates gcc libc6-dev gnupg2 git
308+
309+
# Install optional dependencies (continue if they fail)
310+
case "$PKG_MANAGER" in
311+
apt)
312+
check_packages lldb python3-minimal libpython3.? || true
313+
;;
314+
dnf|yum|microdnf)
315+
check_packages lldb python3 python3-devel || true
316+
;;
317+
tdnf)
318+
check_packages python3 python3-devel || true
319+
# LLDB might not be available in Photon/Mariner
320+
;;
321+
esac
322+
323+
# Get architecture
324+
if command -v dpkg >/dev/null 2>&1; then
325+
architecture="$(dpkg --print-architecture)"
326+
else
327+
architecture="$(uname -m)"
328+
# Convert common architectures to Debian equivalents
329+
case ${architecture} in
330+
x86_64)
331+
architecture="amd64"
332+
;;
333+
aarch64)
334+
architecture="arm64"
335+
;;
336+
esac
142337
fi
143338

144-
architecture="$(dpkg --print-architecture)"
145339
download_architecture="${architecture}"
146340
case ${download_architecture} in
147-
amd64)
341+
amd64|x86_64)
148342
download_architecture="x86_64"
149343
;;
150-
arm64)
344+
arm64|aarch64)
151345
download_architecture="aarch64"
152346
;;
153347
*) echo "(!) Architecture ${architecture} not supported."
@@ -225,7 +419,6 @@ EOF
225419
chmod -R g+r+w "${RUSTUP_HOME}" "${CARGO_HOME}"
226420

227421
# Clean up
228-
rm -rf /var/lib/apt/lists/*
422+
clean_package_cache
229423

230424
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)