diff --git a/src/powershell/install.sh b/src/powershell/install.sh index 4953a49d8..d1eb93d3d 100755 --- a/src/powershell/install.sh +++ b/src/powershell/install.sh @@ -17,18 +17,86 @@ POWERSHELL_MODULES="${MODULES:-""}" POWERSHELL_PROFILE_URL="${POWERSHELLPROFILEURL}" MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc" -POWERSHELL_ARCHIVE_ARCHITECTURES="amd64" +#MICROSOFT_GPG_KEYS_URI=$(curl https://packages.microsoft.com/keys/microsoft.asc -o /usr/share/keyrings/microsoft-archive-keyring.gpg) +POWERSHELL_ARCHIVE_ARCHITECTURES_UBUNTU="amd64" +POWERSHELL_ARCHIVE_ARCHITECTURES_ALMALINUX="x86_64" POWERSHELL_ARCHIVE_VERSION_CODENAMES="stretch buster bionic focal bullseye jammy bookworm noble" GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com keyserver hkp://keyserver.ubuntu.com:80 keyserver hkps://keys.openpgp.org -keyserver hkp://keyserver.pgp.com" +keyserver hkp://keyserver.pgp.com +keyserver hkp://keyserver.fedoraproject.org +keyserver hkps://keys.openpgp.org +keyserver hkp://pgp.mit.edu +keyserver hkp://keyserver.redhat.com" + if [ "$(id -u)" -ne 0 ]; then echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' exit 1 fi +# Clean up package manager cache +clean_cache() { + if [ -d "/var/cache/apt" ]; then + apt-get clean + fi + if [ -d "/var/cache/dnf" ]; then + rm -rf /var/cache/dnf/* + fi +} +# Install dependencies for RHEL/CentOS/AlmaLinux (DNF-based systems) +install_using_dnf() { + dnf remove -y curl-minimal + dnf install -y curl gnupg2 ca-certificates dnf-plugins-core + dnf clean all + dnf makecache + curl --version +} + +# Install PowerShell on RHEL/CentOS/AlmaLinux-based systems (DNF) +install_powershell_dnf() { + # Install wget, if not already installed + dnf install -y wget + + # Download Microsoft GPG key + curl https://packages.microsoft.com/keys/microsoft.asc -o /usr/share/keyrings/microsoft-archive-keyring.gpg + ls -l /usr/share/keyrings/microsoft-archive-keyring.gpg + + # Install necessary dependencies + dnf install -y krb5-libs libicu openssl-libs zlib + + # Add Microsoft PowerShell repository + curl "https://packages.microsoft.com/config/rhel/9.0/prod.repo" > /etc/yum.repos.d/microsoft.repo + + # Install PowerShell + dnf install --assumeyes powershell +} + + +# Detect the package manager and OS +detect_package_manager() { + if [ -f /etc/os-release ]; then + . /etc/os-release + if [[ "$ID" == "ubuntu" || "$ID" == "debian" ]]; then + echo "Detected Debian/Ubuntu-based system" + install_using_apt + install_pwsh + elif [[ "$ID" == "centos" || "$ID" == "rhel" || "$ID" == "almalinux" ]]; then + echo "Detected RHEL/CentOS/AlmaLinux-based system" + install_using_dnf + install_powershell_dnf + install_pwsh + else + echo "Unsupported Linux distribution: $ID" + exit 1 + fi + else + echo "Could not detect OS" + exit 1 + fi +} + # Figure out correct version of a three part version number is not passed find_version_from_git_tags() { local variable_name=$1 @@ -72,10 +140,31 @@ apt_get_update() } # Checks if packages are installed and installs them if not -check_packages() { - if ! dpkg -s "$@" > /dev/null 2>&1; then - apt_get_update - apt-get -y install --no-install-recommends "$@" + check_packages() { + if command -v dpkg > /dev/null 2>&1; then + # If dpkg exists, assume APT-based system (Debian/Ubuntu) + for package in "$@"; do + if ! dpkg -s "$package" > /dev/null 2>&1; then + echo "Package $package not installed. Installing using apt-get..." + sudo apt-get update + sudo apt-get install -y --no-install-recommends "$package" + else + echo "Package $package is already installed (APT)." + fi + done + elif command -v rpm > /dev/null 2>&1 && command -v dnf > /dev/null 2>&1; then + # If rpm and dnf exist, assume DNF-based system (RHEL/AlmaLinux) + for package in "$@"; do + if ! rpm -q "$package" > /dev/null 2>&1; then + echo "Package $package not installed. Installing using dnf..." + dnf install -y "$package" + else + echo "Package $package is already installed (DNF)." + fi + done + else + echo "Unsupported package manager. Neither APT nor DNF found." + return 1 fi } @@ -83,8 +172,10 @@ install_using_apt() { # Install dependencies check_packages apt-transport-https curl ca-certificates gnupg2 dirmngr # Import key safely (new 'signed-by' method rather than deprecated apt-key approach) and install + curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/microsoft-${ID}-${VERSION_CODENAME}-prod ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/microsoft.list + # Update lists apt-get update -yq @@ -202,7 +293,12 @@ install_using_github() { check_packages git fi if [ "${architecture}" = "amd64" ]; then + architecture="amd64" + elif [ "${architecture}" = "x86_64"]; then + architecture="x86_64" + else architecture="x64" + fi pwsh_url="https://github.com/PowerShell/PowerShell" find_version_from_git_tags POWERSHELL_VERSION $pwsh_url @@ -212,7 +308,12 @@ install_using_github() { fi # Ugly - but only way to get sha256 is to parse release HTML. Remove newlines and tags, then look for filename followed by 64 hex characters. - curl -sSL -o "release.html" "https://github.com/PowerShell/PowerShell/releases/tag/v${POWERSHELL_VERSION}" + #curl -sSL -o "release.html" "https://github.com/PowerShell/PowerShell/releases/tag/v${POWERSHELL_VERSION}" + wget https://github.com/PowerShell/PowerShell/releases/download/v${POWERSHELL_VERSION}/${powershell_filename} + mkdir ~/powershell + tar -xvf powershell-${POWERSHELL_VERSION}-linux-x64.tar.gz -C ~/powershell + + powershell_archive_sha256="$(cat release.html | tr '\n' ' ' | sed 's|<[^>]*>||g' | grep -oP "${powershell_filename}\s+\K[0-9a-fA-F]{64}" || echo '')" if [ -z "${powershell_archive_sha256}" ]; then echo "(!) WARNING: Failed to retrieve SHA256 for archive. Skipping validaiton." @@ -233,14 +334,22 @@ if ! type pwsh >/dev/null 2>&1; then # Source /etc/os-release to get OS info . /etc/os-release - architecture="$(dpkg --print-architecture)" + architecture="$(uname -m)" + if [[ "$ID" == "ubuntu" || "$ID" == "debian" ]]; then + POWERSHELL_ARCHIVE_ARCHITECTURES="${POWERSHELL_ARCHIVE_ARCHITECTURES_UBUNTU}" + elif [[ "$ID" == "centos" || "$ID" == "rhel" || "$ID" == "almalinux" ]]; then + POWERSHELL_ARCHIVE_ARCHITECTURES="${POWERSHELL_ARCHIVE_ARCHITECTURES_ALMALINUX}" + fi - if [[ "${POWERSHELL_ARCHIVE_ARCHITECTURES}" = *"${architecture}"* ]] && [[ "${POWERSHELL_ARCHIVE_VERSION_CODENAMES}" = *"${VERSION_CODENAME}"* ]]; then + if [[ "${POWERSHELL_ARCHIVE_ARCHITECTURES}" = *"${POWERSHELL_ARCHIVE_ARCHITECTURES_UBUNTU}"* ]] && [[ "${POWERSHELL_ARCHIVE_VERSION_CODENAMES}" = *"${VERSION_CODENAME}"* ]]; then install_using_apt || use_github="true" - else - use_github="true" - fi + elif [[ "${POWERSHELL_ARCHIVE_ARCHITECTURES}" = *"${POWERSHELL_ARCHIVE_ARCHITECTURES_ALMALINUX}"* ]]; then + install_using_dnf && install_powershell_dnf || use_github="true" + else + use_github="true" + fi + if [ "${use_github}" = "true" ]; then echo "Attempting install from GitHub release..." install_using_github @@ -276,10 +385,10 @@ if [ -n "$POWERSHELL_PROFILE_URL" ]; then echo "Downloading PowerShell Profile from: $POWERSHELL_PROFILE_URL" # Get profile path from currently installed pwsh profilePath=$(pwsh -noni -c '$PROFILE.AllUsersAllHosts') - sudo -E curl -sSL -o "$profilePath" "$POWERSHELL_PROFILE_URL" + -E curl -sSL -o "$profilePath" "$POWERSHELL_PROFILE_URL" fi # Clean up rm -rf /var/lib/apt/lists/* -echo "Done!" +echo "Done!" \ No newline at end of file diff --git a/test/powershell/powershell_alma_linux.sh b/test/powershell/powershell_alma_linux.sh new file mode 100644 index 000000000..8b653afe5 --- /dev/null +++ b/test/powershell/powershell_alma_linux.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -e + +# Import test library for `check` command +source dev-container-features-test-lib + +# Extension-specific tests +check "pwsh file is symlink" bash -c "[ -L /usr/bin/pwsh ]" +check "pwsh symlink is registered as shell" bash -c "[ $(grep -c '/usr/bin/pwsh' /etc/shells) -ge 1 ]" +check "pwsh target is correct" bash -c "[ $(readlink /usr/bin/pwsh) = /opt/microsoft/powershell/7/pwsh ]" +check "pwsh owner is root" bash -c "[ $(stat -c %U /opt/microsoft/powershell/7/pwsh) = root ]" +check "pwsh group is root" bash -c "[ $(stat -c %G /opt/microsoft/powershell/7/pwsh) = root ]" +check "pwsh file mode is -rwxr-xr-x" bash -c "[ $(stat -c '%A' /opt/microsoft/powershell/7/pwsh) = '-rwxr-xr-x' ]" +check "pwsh is in PATH" bash -c "command -v pwsh" + +# Report result +reportResults \ No newline at end of file diff --git a/test/powershell/scenarios.json b/test/powershell/scenarios.json index 87a5b9d16..781ebaf86 100644 --- a/test/powershell/scenarios.json +++ b/test/powershell/scenarios.json @@ -30,5 +30,11 @@ "features": { "powershell": {} } + }, + "powershell_alma_linux": { + "image": "almalinux:9", + "features": { + "powershell": {} + } } }