From e83ed7b0209705490a71fc94280e04e7ac58dad8 Mon Sep 17 00:00:00 2001 From: Gaurav Saini Date: Thu, 28 Mar 2024 03:55:36 +0000 Subject: [PATCH 1/4] [Ruby] - Install using fallback - draft --- src/ruby/install.sh | 126 ++++++++++++-- test/ruby/ruby_fallback_test.sh | 298 ++++++++++++++++++++++++++++++++ test/ruby/scenarios.json | 8 + 3 files changed, 414 insertions(+), 18 deletions(-) create mode 100644 test/ruby/ruby_fallback_test.sh diff --git a/src/ruby/install.sh b/src/ruby/install.sh index 7e4514bba..9bd83e433 100755 --- a/src/ruby/install.sh +++ b/src/ruby/install.sh @@ -30,6 +30,8 @@ keyserver hkp://keyserver.pgp.com" set -e +trap 'echo "Last executed command failed at line ${LINENO}"' ERR + # Clean up rm -rf /var/lib/apt/lists/* @@ -140,6 +142,47 @@ find_version_from_git_tags() { echo "${variable_name}=${!variable_name}" } +# Use semver logic to decrement a version number then look for the closest match +find_prev_version_from_git_tags() { + local variable_name=$1 + local current_version=${!variable_name} + local repository=$2 + # Normally a "v" is used before the version number, but support alternate cases + local prefix=${3:-"tags/v"} + # Some repositories use "_" instead of "." for version number part separation, support that + local separator=${4:-"."} + # Some tools release versions that omit the last digit (e.g. go) + local last_part_optional=${5:-"false"} + # Some repositories may have tags that include a suffix (e.g. actions/node-versions) + local version_suffix_regex=$6 + # Try one break fix version number less if we get a failure. Use "set +e" since "set -e" can cause failures in valid scenarios. + set +e + major="$(echo "${current_version}" | grep -oE '^[0-9]+' || echo '')" + minor="$(echo "${current_version}" | grep -oP '^[0-9]+\.\K[0-9]+' || echo '')" + breakfix="$(echo "${current_version}" | grep -oP '^[0-9]+\.[0-9]+\.\K[0-9]+' 2>/dev/null || echo '')" + + if [ "${minor}" = "0" ] && [ "${breakfix}" = "0" ]; then + ((major=major-1)) + declare -g ${variable_name}="${major}" + # Look for latest version from previous major release + find_version_from_git_tags "${variable_name}" "${repository}" "${prefix}" "${separator}" "${last_part_optional}" + # Handle situations like Go's odd version pattern where "0" releases omit the last part + elif [ "${breakfix}" = "" ] || [ "${breakfix}" = "0" ]; then + ((minor=minor-1)) + declare -g ${variable_name}="${major}.${minor}" + # Look for latest version from previous minor release + find_version_from_git_tags "${variable_name}" "${repository}" "${prefix}" "${separator}" "${last_part_optional}" + else + ((breakfix=breakfix-1)) + if [ "${breakfix}" = "0" ] && [ "${last_part_optional}" = "true" ]; then + declare -g ${variable_name}="${major}.${minor}" + else + declare -g ${variable_name}="${major}.${minor}.${breakfix}" + fi + fi + set -e +} + apt_get_update() { if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then @@ -173,25 +216,45 @@ if ! type git > /dev/null 2>&1; then check_packages git fi +# Function to fetch the version released prior to the latest version +get_previous_version() { + local url=$1 + local repo_url=$2 + local variable_name=$3 + prev_version=${!variable_name} + + output=$(curl -s "$repo_url"); + + #install jq + check_packages jq + + message=$(echo "$output" | jq -r '.message') + + if [[ $message == "API rate limit exceeded"* ]]; then + echo -e "\nAn attempt to find latest version using GitHub Api Failed... \nReason: ${message}" + echo -e "\nAttempting to find latest version using GitHub tags." + find_prev_version_from_git_tags prev_version "$url" "tags/v" + declare -g ${variable_name}="${prev_version}" + else + echo -e "\nAttempting to find latest version using GitHub Api." + version=$(echo "$output" | jq -r '.tag_name' | tr '_' '.') + declare -g ${variable_name}="${version#v}" + fi + echo "${variable_name}=${!variable_name}" +} + +get_github_api_repo_url() { + local url=$1 + echo "${url/https:\/\/github.com/https:\/\/api.github.com\/repos}/releases/latest" +} + # Figure out correct version of a three part version number is not passed -find_version_from_git_tags RUBY_VERSION "https://github.com/ruby/ruby" "tags/v" "_" +ruby_url="https://github.com/ruby/ruby" +find_version_from_git_tags RUBY_VERSION $ruby_url "tags/v" "_" +RUBY_VERSION="3.3.1" -# Just install Ruby if RVM already installed -if rvm --version > /dev/null; then - echo "Ruby Version Manager already exists." - if [[ "$(ruby -v)" = *"${RUBY_VERSION}"* ]]; then - echo "(!) Ruby is already installed with version ${RUBY_VERSION}. Skipping..." - elif [ "${RUBY_VERSION}" != "none" ]; then - echo "Installing specified Ruby version." - su ${USERNAME} -c "rvm install ruby ${RUBY_VERSION}" - fi - SKIP_GEM_INSTALL="false" - SKIP_RBENV_RBUILD="true" -else - # Install RVM - receive_gpg_keys RVM_GPG_KEYS - # Determine appropriate settings for rvm installer +set_rvm_install_args() { if [ "${RUBY_VERSION}" = "none" ]; then RVM_INSTALL_ARGS="" elif [[ "$(ruby -v)" = *"${RUBY_VERSION}"* ]]; then @@ -210,12 +273,39 @@ else DEFAULT_GEMS="" fi fi +} + +install_previous_version() { + repo_url=$(get_github_api_repo_url "$ruby_url") + get_previous_version "${ruby_url}" "${repo_url}" RUBY_VERSION + set_rvm_install_args "$RUBY_VERSION" + curl -sSL https://get.rvm.io | bash -s stable --ignore-dotfiles ${RVM_INSTALL_ARGS} --with-default-gems="${DEFAULT_GEMS}" 2>&1 +} + +# Just install Ruby if RVM already installed +if rvm --version > /dev/null; then + echo "Ruby Version Manager already exists." + if [[ "$(ruby -v)" = *"${RUBY_VERSION}"* ]]; then + echo "(!) Ruby is already installed with version ${RUBY_VERSION}. Skipping..." + elif [ "${RUBY_VERSION}" != "none" ]; then + echo "Installing specified Ruby version." + su ${USERNAME} -c "rvm install ruby ${RUBY_VERSION}" + fi + SKIP_GEM_INSTALL="false" + SKIP_RBENV_RBUILD="true" +else + # Install RVM + receive_gpg_keys RVM_GPG_KEYS + # Determine appropriate settings for rvm installer + + set_rvm_install_args "$RUBY_VERSION" + # Create rvm group as a system group to reduce the odds of conflict with local user UIDs if ! cat /etc/group | grep -e "^rvm:" > /dev/null 2>&1; then groupadd -r rvm fi # Install rvm - curl -sSL https://get.rvm.io | bash -s stable --ignore-dotfiles ${RVM_INSTALL_ARGS} --with-default-gems="${DEFAULT_GEMS}" 2>&1 + curl -sSL https://get.rvm.io | bash -s stable --ignore-dotfiles ${RVM_INSTALL_ARGS} --with-default-gems="${DEFAULT_GEMS}" 2>&1 || install_previous_version usermod -aG rvm ${USERNAME} source /usr/local/rvm/scripts/rvm rvm fix-permissions system @@ -239,7 +329,7 @@ if [ ! -z "${ADDITIONAL_VERSIONS}" ]; then read -a additional_versions <<< "$ADDITIONAL_VERSIONS" for version in "${additional_versions[@]}"; do # Figure out correct version of a three part version number is not passed - find_version_from_git_tags version "https://github.com/ruby/ruby" "tags/v" "_" + find_version_from_git_tags version $ruby_url "tags/v" "_" source /usr/local/rvm/scripts/rvm rvm install ruby ${version} done diff --git a/test/ruby/ruby_fallback_test.sh b/test/ruby/ruby_fallback_test.sh new file mode 100644 index 000000000..0435bf8ae --- /dev/null +++ b/test/ruby/ruby_fallback_test.sh @@ -0,0 +1,298 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +USERNAME="${_REMOTE_USER:-"automatic"}" +set -x +echo -e "\nRuby version installed by ruby feature ..." +check "ruby" ruby -v +check "rake" bash -c "gem list | grep rake" + +trap 'echo "Last executed command failed at line ${LINENO}"' ERR + +RVM_GPG_KEYS="409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB" +GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com +keyserver hkp://keyserver.ubuntu.com:80 +keyserver hkps://keys.openpgp.org +keyserver hkp://keyserver.pgp.com" + +# Clean up +sudo rm -rf /var/lib/apt/lists/* + +# 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 + +# Determine the appropriate non-root user +if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then + USERNAME="" + POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)") + for CURRENT_USER in "${POSSIBLE_USERS[@]}"; do + if id -u ${CURRENT_USER} > /dev/null 2>&1; then + USERNAME=${CURRENT_USER} + break + fi + done + if [ "${USERNAME}" = "" ]; then + USERNAME=root + fi +elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then + USERNAME=root +fi + +# Ensure apt is in non-interactive to avoid prompts +export DEBIAN_FRONTEND=noninteractive + +architecture="$(uname -m)" +if [ "${architecture}" != "amd64" ] && [ "${architecture}" != "x86_64" ] && [ "${architecture}" != "arm64" ] && [ "${architecture}" != "aarch64" ]; then + echo "(!) Architecture $architecture unsupported" + exit 1 +fi + +apt_get_update() +{ + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + echo "Running apt-get update..." + sudo apt-get update -y + fi +} + +# Checks if packages are installed and installs them if not +check_packages() { + if ! dpkg -s "$@" > /dev/null 2>&1; then + apt_get_update + sudo apt-get -y install --no-install-recommends "$@" + fi +} + +# Import the specified key in a variable name passed in as +receive_gpg_keys() { + local keys=${!1} + local keyring_args="" + if [ ! -z "$2" ]; then + keyring_args="--no-default-keyring --keyring \"$2\"" + fi + + # Use a temporary location for gpg keys to avoid polluting image + export GNUPGHOME="/tmp/tmp-gnupg" + sudo mkdir -p ${GNUPGHOME} + sudo chmod 700 ${GNUPGHOME} + echo -e "disable-ipv6\n${GPG_KEY_SERVERS}" > ${GNUPGHOME}/dirmngr.conf + # GPG key download sometimes fails for some reason and retrying fixes it. + local retry_count=0 + local gpg_ok="false" + set +e + until [ "${gpg_ok}" = "true" ] || [ "${retry_count}" -eq "5" ]; + do + echo "(*) Downloading GPG key..." + ( echo "${keys}" | xargs -n 1 gpg -q ${keyring_args} --recv-keys) 2>&1 && gpg_ok="true" + if [ "${gpg_ok}" != "true" ]; then + echo "(*) Failed getting key, retring in 10s..." + (( retry_count++ )) + sleep 10s + fi + done + set -e + if [ "${gpg_ok}" = "false" ]; then + echo "(!) Failed to get gpg key." + 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 + local requested_version=${!variable_name} + if [ "${requested_version}" = "none" ]; then return; fi + local repository=$2 + local prefix=${3:-"tags/v"} + local separator=${4:-"."} + local last_part_optional=${5:-"false"} + if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then + local escaped_separator=${separator//./\\.} + local last_part + if [ "${last_part_optional}" = "true" ]; then + last_part="(${escaped_separator}[0-9]+)?" + else + last_part="${escaped_separator}[0-9]+" + fi + local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$" + local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" + if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then + declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" + else + set +e + declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" + set -e + fi + fi + if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then + echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 + exit 1 + fi + echo "${variable_name}=${!variable_name}" +} + +# Use semver logic to decrement a version number then look for the closest match +find_prev_version_from_git_tags() { + local variable_name=$1 + local current_version=${!variable_name} + local repository=$2 + # Normally a "v" is used before the version number, but support alternate cases + local prefix=${3:-"tags/v"} + # Some repositories use "_" instead of "." for version number part separation, support that + local separator=${4:-"."} + # Some tools release versions that omit the last digit (e.g. go) + local last_part_optional=${5:-"false"} + # Some repositories may have tags that include a suffix (e.g. actions/node-versions) + local version_suffix_regex=$6 + # Try one break fix version number less if we get a failure. Use "set +e" since "set -e" can cause failures in valid scenarios. + set +e + major="$(echo "${current_version}" | grep -oE '^[0-9]+' || echo '')" + minor="$(echo "${current_version}" | grep -oP '^[0-9]+\.\K[0-9]+' || echo '')" + breakfix="$(echo "${current_version}" | grep -oP '^[0-9]+\.[0-9]+\.\K[0-9]+' 2>/dev/null || echo '')" + + if [ "${minor}" = "0" ] && [ "${breakfix}" = "0" ]; then + ((major=major-1)) + declare -g ${variable_name}="${major}" + # Look for latest version from previous major release + find_version_from_git_tags "${variable_name}" "${repository}" "${prefix}" "${separator}" "${last_part_optional}" + # Handle situations like Go's odd version pattern where "0" releases omit the last part + elif [ "${breakfix}" = "" ] || [ "${breakfix}" = "0" ]; then + ((minor=minor-1)) + declare -g ${variable_name}="${major}.${minor}" + # Look for latest version from previous minor release + find_version_from_git_tags "${variable_name}" "${repository}" "${prefix}" "${separator}" "${last_part_optional}" + else + ((breakfix=breakfix-1)) + if [ "${breakfix}" = "0" ] && [ "${last_part_optional}" = "true" ]; then + declare -g ${variable_name}="${major}.${minor}" + else + declare -g ${variable_name}="${major}.${minor}.${breakfix}" + fi + fi + set -e +} + +# Function to fetch the version released prior to the latest version +get_previous_version() { + local url=$1 + local repo_url=$2 + local variable_name=$3 + local mode=$4 + prev_version=${!variable_name} + + output=$(sudo curl -s "$repo_url"); + + #install jq + check_packages jq + + message=$(echo "$output" | jq -r '.message') + + if [[ $mode == "mode1" ]]; then + message="API rate limit exceeded" + else + message="" + fi + + if [[ $message == "API rate limit exceeded"* ]]; then + echo -e "\nAn attempt to find latest version using GitHub Api Failed... \nReason: ${message}" + echo -e "\nAttempting to find latest version using GitHub tags." + find_prev_version_from_git_tags prev_version "$url" "tags/v" + declare -g ${variable_name}="${prev_version}" + else + echo -e "\nAttempting to find latest version using GitHub Api." + version=$(echo "$output" | jq -r '.tag_name' | tr '_' '.') + declare -g ${variable_name}="${version#v}" + fi + echo "${variable_name}=${!variable_name}" +} + +get_github_api_repo_url() { + local url=$1 + echo "${url/https:\/\/github.com/https:\/\/api.github.com\/repos}/releases/latest" +} + + +# Figure out correct version of a three part version number is not passed +ruby_url="https://github.com/ruby/ruby" + +RUBY_VERSION="3.3.xyz" + +set_rvm_install_args() { + if [ "${RUBY_VERSION}" = "none" ]; then + RVM_INSTALL_ARGS="" + elif [[ "$(ruby -v)" = *"${RUBY_VERSION}"* ]]; then + echo "(!) Ruby is already installed with version ${RUBY_VERSION}. Skipping..." + RVM_INSTALL_ARGS="" + else + if [ "${RUBY_VERSION}" = "latest" ] || [ "${RUBY_VERSION}" = "current" ] || [ "${RUBY_VERSION}" = "lts" ]; then + RVM_INSTALL_ARGS="--ruby" + RUBY_VERSION="" + else + RVM_INSTALL_ARGS="--ruby=${RUBY_VERSION}" + fi + if [ "${INSTALL_RUBY_TOOLS}" = "true" ]; then + SKIP_GEM_INSTALL="true" + else + DEFAULT_GEMS="" + fi + fi +} + +install_previous_version() { + mode=$1 + repo_url=$(get_github_api_repo_url "$ruby_url") + get_previous_version "${ruby_url}" "${repo_url}" RUBY_VERSION $mode + set_rvm_install_args "$RUBY_VERSION" + sudo curl -sSL https://get.rvm.io | bash -s stable --ignore-dotfiles ${RVM_INSTALL_ARGS} --with-default-gems="${DEFAULT_GEMS}" 2>&1 +} + +install_ruby() { + mode=$1 + if rvm --version > /dev/null; then + echo "Ruby Version Manager already exists." + if [[ "$(ruby -v)" = *"${RUBY_VERSION}"* ]]; then + echo "(!) Ruby is already installed with version ${RUBY_VERSION}. Skipping..." + elif [ "${RUBY_VERSION}" != "none" ]; then + echo "Installing specified Ruby version." + su ${USERNAME} -c "rvm install ruby ${RUBY_VERSION}" + fi + SKIP_GEM_INSTALL="false" + SKIP_RBENV_RBUILD="true" + else + # Install RVM + receive_gpg_keys RVM_GPG_KEYS + # Determine appropriate settings for rvm installer + + set_rvm_install_args "$RUBY_VERSION" + + # Create rvm group as a system group to reduce the odds of conflict with local user UIDs + if ! cat /etc/group | grep -e "^rvm:" > /dev/null 2>&1; then + groupadd -r rvm + fi + # Install rvm + sudo curl -sSL https://get.rvm.io | bash -s stable --ignore-dotfiles ${RVM_INSTALL_ARGS} --with-default-gems="${DEFAULT_GEMS}" 2>&1 || install_previous_version "$mode" + sudo usermod -aG rvm ${USERNAME} + sudo source /usr/local/rvm/scripts/rvm + sudo rvm fix-permissions system + sudo rm -rf ${GNUPGHOME} + fi +} + +install_ruby "mode1" +echo -e "\nRuby version installed by ruby test for fallback ... (mode: 1 - install using find_prev_version_from_git_tags):" +check "ruby" ruby -v +check "rake" bash -c "gem list | grep rake" + +install_ruby "mode2" +echo -e "\nRuby version installed by ruby test for fallback ... (mode: 1 - install using GitHub Api):" +check "ruby" ruby -v +check "rake" bash -c "gem list | grep rake" +set +x +# Report result +reportResults \ No newline at end of file diff --git a/test/ruby/scenarios.json b/test/ruby/scenarios.json index 04cac73f5..cfa2d8554 100644 --- a/test/ruby/scenarios.json +++ b/test/ruby/scenarios.json @@ -13,5 +13,13 @@ "features": { "ruby": {} } + }, + "ruby_fallback_test": { + "image": "mcr.microsoft.com/devcontainers/base:bullseye", + "features": { + "ruby": { + "version": "latest" + } + } } } \ No newline at end of file From 6d4fc5560e223c1123aca3a7c6e198ea0b43647a Mon Sep 17 00:00:00 2001 From: Gaurav Saini Date: Tue, 2 Apr 2024 05:17:23 +0000 Subject: [PATCH 2/4] [Ruby] - Rvm - fallback logic implementation --- src/ruby/install.sh | 11 ++-- test/ruby/ruby_fallback_test.sh | 90 +++++++++++++-------------------- 2 files changed, 40 insertions(+), 61 deletions(-) diff --git a/src/ruby/install.sh b/src/ruby/install.sh index 9bd83e433..073d982a9 100755 --- a/src/ruby/install.sh +++ b/src/ruby/install.sh @@ -229,11 +229,11 @@ get_previous_version() { check_packages jq message=$(echo "$output" | jq -r '.message') - + if [[ $message == "API rate limit exceeded"* ]]; then echo -e "\nAn attempt to find latest version using GitHub Api Failed... \nReason: ${message}" echo -e "\nAttempting to find latest version using GitHub tags." - find_prev_version_from_git_tags prev_version "$url" "tags/v" + find_prev_version_from_git_tags prev_version "$url" "tags/v" "_" declare -g ${variable_name}="${prev_version}" else echo -e "\nAttempting to find latest version using GitHub Api." @@ -252,7 +252,6 @@ get_github_api_repo_url() { # Figure out correct version of a three part version number is not passed ruby_url="https://github.com/ruby/ruby" find_version_from_git_tags RUBY_VERSION $ruby_url "tags/v" "_" -RUBY_VERSION="3.3.1" set_rvm_install_args() { if [ "${RUBY_VERSION}" = "none" ]; then @@ -278,7 +277,7 @@ set_rvm_install_args() { install_previous_version() { repo_url=$(get_github_api_repo_url "$ruby_url") get_previous_version "${ruby_url}" "${repo_url}" RUBY_VERSION - set_rvm_install_args "$RUBY_VERSION" + set_rvm_install_args curl -sSL https://get.rvm.io | bash -s stable --ignore-dotfiles ${RVM_INSTALL_ARGS} --with-default-gems="${DEFAULT_GEMS}" 2>&1 } @@ -298,7 +297,7 @@ else receive_gpg_keys RVM_GPG_KEYS # Determine appropriate settings for rvm installer - set_rvm_install_args "$RUBY_VERSION" + set_rvm_install_args # Create rvm group as a system group to reduce the odds of conflict with local user UIDs if ! cat /etc/group | grep -e "^rvm:" > /dev/null 2>&1; then @@ -312,7 +311,7 @@ else rm -rf ${GNUPGHOME} fi -if [ "${INSTALL_RUBY_TOOLS}" = "true" ]; then +if [ "${INSTALL_RUBY_TOOLS}" = "true" ]; then # Non-root user may not have "gem" in path when script is run and no ruby version # is installed by rvm, so handle this by using root's default gem in this case ROOT_GEM="$(which gem || echo "")" diff --git a/test/ruby/ruby_fallback_test.sh b/test/ruby/ruby_fallback_test.sh index 0435bf8ae..4c79f9a40 100644 --- a/test/ruby/ruby_fallback_test.sh +++ b/test/ruby/ruby_fallback_test.sh @@ -5,11 +5,10 @@ set -e # Optional: Import test library source dev-container-features-test-lib -USERNAME="${_REMOTE_USER:-"automatic"}" -set -x -echo -e "\nRuby version installed by ruby feature ..." +USERNAME="automatic" +echo -e "\nRVM version installed previously by ruby feature ..." +check "rvm" rvm --version check "ruby" ruby -v -check "rake" bash -c "gem list | grep rake" trap 'echo "Last executed command failed at line ${LINENO}"' ERR @@ -20,12 +19,7 @@ keyserver hkps://keys.openpgp.org keyserver hkp://keyserver.pgp.com" # Clean up -sudo rm -rf /var/lib/apt/lists/* - -# 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 +rm -rf /var/lib/apt/lists/* # Determine the appropriate non-root user if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then @@ -57,7 +51,7 @@ apt_get_update() { if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then echo "Running apt-get update..." - sudo apt-get update -y + apt-get update -y fi } @@ -65,7 +59,7 @@ apt_get_update() check_packages() { if ! dpkg -s "$@" > /dev/null 2>&1; then apt_get_update - sudo apt-get -y install --no-install-recommends "$@" + apt-get -y install --no-install-recommends "$@" fi } @@ -79,9 +73,9 @@ receive_gpg_keys() { # Use a temporary location for gpg keys to avoid polluting image export GNUPGHOME="/tmp/tmp-gnupg" - sudo mkdir -p ${GNUPGHOME} - sudo chmod 700 ${GNUPGHOME} - echo -e "disable-ipv6\n${GPG_KEY_SERVERS}" > ${GNUPGHOME}/dirmngr.conf + mkdir -p ${GNUPGHOME} + chmod 700 ${GNUPGHOME} + echo -e "disable-ipv6\n${GPG_KEY_SERVERS}" | tee ${GNUPGHOME}/dirmngr.conf > /dev/null # GPG key download sometimes fails for some reason and retrying fixes it. local retry_count=0 local gpg_ok="false" @@ -186,7 +180,7 @@ get_previous_version() { local mode=$4 prev_version=${!variable_name} - output=$(sudo curl -s "$repo_url"); + output=$(curl -s "$repo_url"); #install jq check_packages jq @@ -202,7 +196,7 @@ get_previous_version() { if [[ $message == "API rate limit exceeded"* ]]; then echo -e "\nAn attempt to find latest version using GitHub Api Failed... \nReason: ${message}" echo -e "\nAttempting to find latest version using GitHub tags." - find_prev_version_from_git_tags prev_version "$url" "tags/v" + find_prev_version_from_git_tags prev_version "$url" "tags/v" "_" declare -g ${variable_name}="${prev_version}" else echo -e "\nAttempting to find latest version using GitHub Api." @@ -221,7 +215,7 @@ get_github_api_repo_url() { # Figure out correct version of a three part version number is not passed ruby_url="https://github.com/ruby/ruby" -RUBY_VERSION="3.3.xyz" +RUBY_VERSION="3.1.xyz" set_rvm_install_args() { if [ "${RUBY_VERSION}" = "none" ]; then @@ -248,51 +242,37 @@ install_previous_version() { mode=$1 repo_url=$(get_github_api_repo_url "$ruby_url") get_previous_version "${ruby_url}" "${repo_url}" RUBY_VERSION $mode - set_rvm_install_args "$RUBY_VERSION" - sudo curl -sSL https://get.rvm.io | bash -s stable --ignore-dotfiles ${RVM_INSTALL_ARGS} --with-default-gems="${DEFAULT_GEMS}" 2>&1 + set_rvm_install_args + curl -sSL https://get.rvm.io | bash -s stable --ignore-dotfiles ${RVM_INSTALL_ARGS} --with-default-gems="${DEFAULT_GEMS}" 2>&1 } -install_ruby() { +install_rvm() { mode=$1 - if rvm --version > /dev/null; then - echo "Ruby Version Manager already exists." - if [[ "$(ruby -v)" = *"${RUBY_VERSION}"* ]]; then - echo "(!) Ruby is already installed with version ${RUBY_VERSION}. Skipping..." - elif [ "${RUBY_VERSION}" != "none" ]; then - echo "Installing specified Ruby version." - su ${USERNAME} -c "rvm install ruby ${RUBY_VERSION}" - fi - SKIP_GEM_INSTALL="false" - SKIP_RBENV_RBUILD="true" - else - # Install RVM - receive_gpg_keys RVM_GPG_KEYS - # Determine appropriate settings for rvm installer + # Install RVM + receive_gpg_keys RVM_GPG_KEYS + # Determine appropriate settings for rvm installer - set_rvm_install_args "$RUBY_VERSION" + set_rvm_install_args - # Create rvm group as a system group to reduce the odds of conflict with local user UIDs - if ! cat /etc/group | grep -e "^rvm:" > /dev/null 2>&1; then - groupadd -r rvm - fi - # Install rvm - sudo curl -sSL https://get.rvm.io | bash -s stable --ignore-dotfiles ${RVM_INSTALL_ARGS} --with-default-gems="${DEFAULT_GEMS}" 2>&1 || install_previous_version "$mode" - sudo usermod -aG rvm ${USERNAME} - sudo source /usr/local/rvm/scripts/rvm - sudo rvm fix-permissions system - sudo rm -rf ${GNUPGHOME} + # Create rvm group as a system group to reduce the odds of conflict with local user UIDs + if ! cat /etc/group | grep -e "^rvm:" > /dev/null 2>&1; then + groupadd -r rvm fi + # Install rvm + curl -sSL https://get.rvm.io | bash -s stable --ignore-dotfiles ${RVM_INSTALL_ARGS} --with-default-gems="${DEFAULT_GEMS}" 2>&1 || install_previous_version "$mode" + sudo usermod -aG rvm ${USERNAME} + source /usr/local/rvm/scripts/rvm + rvm fix-permissions system + rm -rf ${GNUPGHOME} } -install_ruby "mode1" -echo -e "\nRuby version installed by ruby test for fallback ... (mode: 1 - install using find_prev_version_from_git_tags):" -check "ruby" ruby -v -check "rake" bash -c "gem list | grep rake" +install_rvm "mode1" +echo -e "\n👉🏻👉🏻RVM version installed by test file ... (mode: 1 - install using find_prev_version_from_git_tags):" +check "rvm" rvm --version + +install_rvm "mode2" +echo -e "\n👉🏻👉🏻RVM version installed by test file ... (mode: 1 - install using GitHub Api):" +check "rvm" rvm --version -install_ruby "mode2" -echo -e "\nRuby version installed by ruby test for fallback ... (mode: 1 - install using GitHub Api):" -check "ruby" ruby -v -check "rake" bash -c "gem list | grep rake" -set +x # Report result reportResults \ No newline at end of file From b0dd609d416a8cfd11877b9e25b272a855e55453 Mon Sep 17 00:00:00 2001 From: Gaurav Saini Date: Tue, 2 Apr 2024 05:21:03 +0000 Subject: [PATCH 3/4] misc changes --- src/ruby/devcontainer-feature.json | 2 +- src/ruby/install.sh | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ruby/devcontainer-feature.json b/src/ruby/devcontainer-feature.json index 73bcbcced..3722cab06 100644 --- a/src/ruby/devcontainer-feature.json +++ b/src/ruby/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ruby", - "version": "1.2.0", + "version": "1.2.1", "name": "Ruby (via rvm)", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/ruby", "description": "Installs Ruby, rvm, rbenv, common Ruby utilities, and needed dependencies.", diff --git a/src/ruby/install.sh b/src/ruby/install.sh index 073d982a9..a1119d1f2 100755 --- a/src/ruby/install.sh +++ b/src/ruby/install.sh @@ -30,8 +30,6 @@ keyserver hkp://keyserver.pgp.com" set -e -trap 'echo "Last executed command failed at line ${LINENO}"' ERR - # Clean up rm -rf /var/lib/apt/lists/* From b62c629dde5421182063cfc32bcd2a83e7c4af6d Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Wed, 3 Apr 2024 01:15:59 +0000 Subject: [PATCH 4/4] changes for review comments.. --- src/ruby/install.sh | 26 +++++++++++++++----------- test/ruby/ruby_fallback_test.sh | 7 +++---- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/ruby/install.sh b/src/ruby/install.sh index a1119d1f2..8f95829da 100755 --- a/src/ruby/install.sh +++ b/src/ruby/install.sh @@ -218,7 +218,7 @@ fi get_previous_version() { local url=$1 local repo_url=$2 - local variable_name=$3 + variable_name=$3 prev_version=${!variable_name} output=$(curl -s "$repo_url"); @@ -248,10 +248,12 @@ get_github_api_repo_url() { # Figure out correct version of a three part version number is not passed -ruby_url="https://github.com/ruby/ruby" -find_version_from_git_tags RUBY_VERSION $ruby_url "tags/v" "_" +RUBY_URL="https://github.com/ruby/ruby" +ORIGINAL_RUBY_VERSION=$RUBY_VERSION +find_version_from_git_tags RUBY_VERSION $RUBY_URL "tags/v" "_" set_rvm_install_args() { + RUBY_VERSION=$1 if [ "${RUBY_VERSION}" = "none" ]; then RVM_INSTALL_ARGS="" elif [[ "$(ruby -v)" = *"${RUBY_VERSION}"* ]]; then @@ -273,10 +275,14 @@ set_rvm_install_args() { } install_previous_version() { - repo_url=$(get_github_api_repo_url "$ruby_url") - get_previous_version "${ruby_url}" "${repo_url}" RUBY_VERSION - set_rvm_install_args - curl -sSL https://get.rvm.io | bash -s stable --ignore-dotfiles ${RVM_INSTALL_ARGS} --with-default-gems="${DEFAULT_GEMS}" 2>&1 + if [[ $ORIGINAL_RUBY_VERSION == "latest" ]]; then + repo_url=$(get_github_api_repo_url "$RUBY_URL") + get_previous_version "${RUBY_URL}" "${repo_url}" RUBY_VERSION + set_rvm_install_args $RUBY_VERSION + curl -sSL https://get.rvm.io | bash -s stable --ignore-dotfiles ${RVM_INSTALL_ARGS} --with-default-gems="${DEFAULT_GEMS}" 2>&1 + else + echo "Failed to install Ruby version $ORIGINAL_RUBY_VERSION. Exiting..." + fi } # Just install Ruby if RVM already installed @@ -294,9 +300,7 @@ else # Install RVM receive_gpg_keys RVM_GPG_KEYS # Determine appropriate settings for rvm installer - - set_rvm_install_args - + set_rvm_install_args $RUBY_VERSION # Create rvm group as a system group to reduce the odds of conflict with local user UIDs if ! cat /etc/group | grep -e "^rvm:" > /dev/null 2>&1; then groupadd -r rvm @@ -326,7 +330,7 @@ if [ ! -z "${ADDITIONAL_VERSIONS}" ]; then read -a additional_versions <<< "$ADDITIONAL_VERSIONS" for version in "${additional_versions[@]}"; do # Figure out correct version of a three part version number is not passed - find_version_from_git_tags version $ruby_url "tags/v" "_" + find_version_from_git_tags version $RUBY_URL "tags/v" "_" source /usr/local/rvm/scripts/rvm rvm install ruby ${version} done diff --git a/test/ruby/ruby_fallback_test.sh b/test/ruby/ruby_fallback_test.sh index 4c79f9a40..fe1a9c77b 100644 --- a/test/ruby/ruby_fallback_test.sh +++ b/test/ruby/ruby_fallback_test.sh @@ -218,6 +218,7 @@ ruby_url="https://github.com/ruby/ruby" RUBY_VERSION="3.1.xyz" set_rvm_install_args() { + RUBY_VERSION=$1 if [ "${RUBY_VERSION}" = "none" ]; then RVM_INSTALL_ARGS="" elif [[ "$(ruby -v)" = *"${RUBY_VERSION}"* ]]; then @@ -242,7 +243,7 @@ install_previous_version() { mode=$1 repo_url=$(get_github_api_repo_url "$ruby_url") get_previous_version "${ruby_url}" "${repo_url}" RUBY_VERSION $mode - set_rvm_install_args + set_rvm_install_args $RUBY_VERSION curl -sSL https://get.rvm.io | bash -s stable --ignore-dotfiles ${RVM_INSTALL_ARGS} --with-default-gems="${DEFAULT_GEMS}" 2>&1 } @@ -251,9 +252,7 @@ install_rvm() { # Install RVM receive_gpg_keys RVM_GPG_KEYS # Determine appropriate settings for rvm installer - - set_rvm_install_args - + set_rvm_install_args $RUBY_VERSION # Create rvm group as a system group to reduce the odds of conflict with local user UIDs if ! cat /etc/group | grep -e "^rvm:" > /dev/null 2>&1; then groupadd -r rvm