diff --git a/src/elixir-asdf/install.sh b/src/elixir-asdf/install.sh index b9623a7..921369f 100755 --- a/src/elixir-asdf/install.sh +++ b/src/elixir-asdf/install.sh @@ -1,24 +1,144 @@ #!/usr/bin/env bash +# This is part of devcontainers-extra script library +# source: https://github.com/devcontainers-extra/features -set -e +set -ex -source ./library_scripts.sh +VERSION=${VERSION:-"latest"} -# nanolayer is a cli utility which keeps container layers as small as possible -# source code: https://github.com/devcontainers-extra/nanolayer -# `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, -# and if missing - will download a temporary copy that automatically get deleted at the end -# of the script -ensure_nanolayer nanolayer_location "v0.4.45" +# Clean up +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 -$nanolayer_location \ - install \ - devcontainer-feature \ - "ghcr.io/devcontainers-extra/features/asdf-package:1.0.8" \ - --option plugin='elixir' --option version="$VERSION" +check_alpine_packages() { + apk add -v --no-cache "$@" +} +check_packages() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + echo "Running apt-get update..." + apt-get update -y + fi + apt-get -y install --no-install-recommends "$@" + fi +} +updaterc() { + if cat /etc/os-release | grep "ID_LIKE=.*alpine.*\|ID=.*alpine.*" ; then + echo "Updating /etc/profile" + echo -e "$1" >>/etc/profile + fi + if [[ "$(cat /etc/bash.bashrc)" != *"$1"* ]]; then + echo "Updating /etc/bash.bashrc" + echo -e "$1" >>/etc/bash.bashrc + fi + if [ -f "/etc/zsh/zshrc" ] && [[ "$(cat /etc/zsh/zshrc)" != *"$1"* ]]; then + echo "Updating /etc/zsh/zshrc" + echo -e "$1" >>/etc/zsh/zshrc + fi +} -echo 'Done!' +install_via_asdf() { + PLUGIN=$1 + VERSION=$2 + REPO=$3 + # install git and curl if does not exists + if cat /etc/os-release | grep "ID_LIKE=.*alpine.*\|ID=.*alpine.*" ; then + check_alpine_packages curl git ca-certificates + elif cat /etc/os-release | grep "ID_LIKE=.*debian.*\|ID=.*debian.*"; then + check_packages curl git ca-certificates + fi + + + # asdf may be installed somewhere on the machine, but we need it to be accessible to the remote user + # the code bellow will return 2 only when asdf is available, and 1 otherwise + set +e + su "$_REMOTE_USER" </dev/null 2>&1; then + exit 2 + fi + exit 1 +EOF + exit_code=$? + set -e + + if [ "${exit_code}" -eq 2 ]; then + # asdf already available to remote user, use it + su "$_REMOTE_USER" </dev/null 2>&1; then + echo "$PLUGIN already exists - skipping adding it" + else + asdf plugin add "$PLUGIN" "$REPO" + fi + + if [ "${VERSION}" = "latest" ] ; then + resolved_version=\$(asdf latest "$PLUGIN" "$LATESTVERSIONPATTERN") + else + resolved_version=$VERSION + fi + + asdf install "$PLUGIN" "\$resolved_version" + asdf global "$PLUGIN" "\$resolved_version" +EOF + else + # asdf is not available to remote user, install it, then update rc files + + su "$_REMOTE_USER" <&1 + + . "\$HOME/.asdf/asdf.sh" + if asdf list "$PLUGIN" >/dev/null 2>&1; then + echo "$PLUGIN already exists - skipping adding it" + else + asdf plugin add "$PLUGIN" "$REPO" + fi +EOF + + + # I resolve the version like this because in bash resolving + # a subshell take prevedent to su, so we must resolve variables + # pre using them in final su clause. + # I hate bash. + resolved_version=$(su "$_REMOTE_USER" < /dev/null 2>&1 + + if [ "${VERSION}" = "latest" ] ; then + asdf latest "$PLUGIN" "$LATESTVERSIONPATTERN" + else + echo $VERSION + fi +EOF +) + su "$_REMOTE_USER" </dev/null 2>&1; then - downloader=curl - elif type wget >/dev/null 2>&1; then - downloader=wget - else - downloader="" - fi - - # in case none of them is installed, install wget temporarly - if [ -z $downloader ] ; then - if [ -x "/usr/bin/apt-get" ] ; then - _apt_get_install $tempdir - elif [ -x "/sbin/apk" ] ; then - _apk_install $tempdir - else - echo "distro not supported" - exit 1 - fi - downloader="wget" - downloader_installed="true" - fi - - if [ $downloader = "wget" ] ; then - wget -q $url -O $output_location - else - curl -sfL $url -o $output_location - fi - - # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because - # alpine lack bash, and RETURN is not a valid signal under sh shell - if ! [ -z $downloader_installed ] ; then - if [ -x "/usr/bin/apt-get" ] ; then - _apt_get_cleanup $tempdir - elif [ -x "/sbin/apk" ] ; then - _apk_cleanup $tempdir - else - echo "distro not supported" - exit 1 - fi - fi - -} - - -ensure_nanolayer() { - # Ensure existance of the nanolayer cli program - local variable_name=$1 - - local required_version=$2 - # normalize version - if ! [[ $required_version == v* ]]; then - required_version=v$required_version - fi - - local nanolayer_location="" - - # If possible - try to use an already installed nanolayer - if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then - if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then - if type nanolayer >/dev/null 2>&1; then - echo "Found a pre-existing nanolayer in PATH" - nanolayer_location=nanolayer - fi - elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ] ; then - nanolayer_location=${NANOLAYER_CLI_LOCATION} - echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" - fi - - # make sure its of the required version - if ! [[ -z "${nanolayer_location}" ]]; then - local current_version - current_version=$($nanolayer_location --version) - if ! [[ $current_version == v* ]]; then - current_version=v$current_version - fi - - if ! [ $current_version == $required_version ]; then - echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" - nanolayer_location="" - fi - fi - - fi - - # If not previuse installation found, download it temporarly and delete at the end of the script - if [[ -z "${nanolayer_location}" ]]; then - - if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then - tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) - - clean_up () { - ARG=$? - rm -rf $tmp_dir - exit $ARG - } - trap clean_up EXIT - - - if [ -x "/sbin/apk" ] ; then - clib_type=musl - else - clib_type=gnu - fi - - tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz - - # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed - clean_download https://github.com/devcontainers-extra/nanolayer/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename - - tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" - chmod a+x $tmp_dir/nanolayer - nanolayer_location=$tmp_dir/nanolayer - - - else - echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" - exit 1 - fi - fi - - # Expose outside the resolved location - declare -g ${variable_name}=$nanolayer_location - -} - - diff --git a/src/erlang-asdf/install.sh b/src/erlang-asdf/install.sh index a377a09..c0e0f3f 100755 --- a/src/erlang-asdf/install.sh +++ b/src/erlang-asdf/install.sh @@ -61,7 +61,10 @@ install_via_asdf() { # asdf may be installed somewhere on the machine, but we need it to be accessible to the remote user # the code bellow will return 2 only when asdf is available, and 1 otherwise set +e - su - "$_REMOTE_USER" </dev/null 2>&1; then exit 2 fi @@ -72,7 +75,9 @@ EOF if [ "${exit_code}" -eq 2 ]; then # asdf already available to remote user, use it - su - "$_REMOTE_USER" </dev/null 2>&1; then echo "$PLUGIN already exists - skipping adding it" @@ -81,35 +86,35 @@ EOF fi if [ "${VERSION}" = "latest" ] ; then - resolved_version=$(asdf latest "$PLUGIN" "$LATESTVERSIONPATTERN") + resolved_version=\$(asdf latest "$PLUGIN" "$LATESTVERSIONPATTERN") else resolved_version=$VERSION fi export KERL_CONFIGURE_OPTIONS="$KERL_CONFIGURE_OPTIONS" - asdf install "$PLUGIN" "$resolved_version" - asdf global "$PLUGIN" "$resolved_version" + asdf install "$PLUGIN" "\$resolved_version" + asdf global "$PLUGIN" "\$resolved_version" EOF else # asdf is not available to remote user, install it, then update rc files + su "$_REMOTE_USER" <&1 + "https://github.com/asdf-vm/asdf.git" --branch v0.12.0 "\$HOME/.asdf" 2>&1 - . $_REMOTE_USER_HOME/.asdf/asdf.sh + . "\$HOME/.asdf/asdf.sh" if asdf list "$PLUGIN" >/dev/null 2>&1; then echo "$PLUGIN already exists - skipping adding it" else asdf plugin add "$PLUGIN" "$REPO" fi - EOF @@ -117,8 +122,9 @@ EOF # a subshell take prevedent to su, so we must resolve variables # pre using them in final su clause. # I hate bash. - resolved_version=$(su - "$_REMOTE_USER" < /dev/null 2>&1 + resolved_version=$(su "$_REMOTE_USER" < /dev/null 2>&1 if [ "${VERSION}" = "latest" ] ; then asdf latest "$PLUGIN" "$LATESTVERSIONPATTERN" @@ -127,15 +133,15 @@ EOF fi EOF ) - su - "$_REMOTE_USER" <