Created
February 27, 2026 15:58
-
-
Save rleap-m/5f023fec27e82a68032de59f2ffdd5a7 to your computer and use it in GitHub Desktop.
This is install.sh but from this PR https://github.com/Mirantis/docker-install-ee/pull/195
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # | |
| # Mirantis Container Runtime installer | |
| # | |
| # Script build information: | |
| # COMMIT_SHA=thisisafakeshamadebyrleap | |
| # COMMIT_SHA_PVAL=thisisa | |
| # SEMVER_VERSION=1.0.25 | |
| # PUBLISH_STRING=test | |
| # ENV VARIABLES: | |
| # Essential: | |
| # - DOCKER_URL - URL to package repo | |
| # - CHANNEL - channel in the package repo | |
| # - VERSION - MCR release version | |
| # Optional: | |
| # - CONTAINERD_VERSION - Containerd package version | |
| # - ADDITIONAL_RUNTIMES - additional runtimes to install (default: empty) (only for 25.x and newer) | |
| # Development: | |
| # - DRY_RUN - installation will be with dry-run flag | |
| # - SKIP_REPO_SETUP - the current configured repos will be only used | |
| # DOCKER_URL and CHANNEL will be ignored | |
| # | |
| set -e | |
| MCR_MAIN_VERSION="" | |
| DIST_ID="" | |
| DOCKER_PACKAGE_NAME="docker-ee" | |
| DOCKER_CLI_PACKAGE_NAME="${DOCKER_PACKAGE_NAME}-cli" | |
| DOCKER_ROOTLESS_PACKAGE_NAME="${DOCKER_PACKAGE_NAME}-rootless-extras" | |
| CONTAINERD_PACKAGE_NAME="containerd.io" | |
| CRI_DOCKERD_PACKAGE_NAME="cri-dockerd-ee" | |
| RUNC_PACKAGE_NAME="runc-ee" | |
| MIN_ROOTLESS_VER="20.10.12" | |
| MIN_MCR_WITH_C8D_VER="23.0.1" | |
| SH_C='sh -c' | |
| # Parse an MCR product version string. | |
| # | |
| # If the version is well-formed, this function exits with a success status | |
| # and the parsed components of the version are placed into $BASH_REMATCH. | |
| # | |
| # ${BASH_REMATCH[1]} - the MAJOR.MINOR.PATCH | |
| # ${BASH_REMATCH[3]} - the tp or rc designator | |
| # ${BASH_REMATCH[4]} - the pre-release increment or hotfix number | |
| # | |
| # Consider the following versions that we might support: | |
| # 23.0.12 - A version by itself. Install latest release build. | |
| # 23.0.12-0 - A specific build version. We use these, for example, if the | |
| # 23.0.12-1 we need to rebuild with a new fipster. | |
| # 23.0.13-tp1 - A specific tp version | |
| # 23.0.13-tp2 | |
| # 23.0.13-rc1 - A specific rc version | |
| # 23.0.13-rc2 | |
| # | |
| function mcr_ver() { | |
| [[ $1 =~ ^([0-9]+\.[0-9]+\.[0-9]+)(-([1-9][0-9]*))?(-(tp|rc)([1-9][0-9]*))?$ ]] | |
| } | |
| get_dep_package_version_deb(){ | |
| local package="${1:?Please specify package name}" | |
| local version="${2:?Please specify package version}" | |
| local dep_package="${3:?Please specify dependance package name}" | |
| apt-cache show "${package}=${version}" \ | |
| | grep -oP "${dep_package}"' \([^ ]+ \K[^\)]+' | |
| } | |
| get_dep_package_version_yum(){ | |
| local package="${1:?Please specify package name}" | |
| local version="${2:?Please specify package version}" | |
| local dep_pkg="${3:?Please specify dependance package name}" | |
| ${SH_C} "yum deplist ${package}-${version}" \ | |
| | awk -v dep_pkg="${dep_pkg}" '$1 == "dependency:" && $2 == dep_pkg {print $4}' | |
| } | |
| get_dep_package_version_zypper(){ | |
| local package="${1:?Please specify package name}" | |
| local version="${2:?Please specify package version}" | |
| local dep_package="${3:?Please specify dependance package name}" | |
| local _full_package_version | |
| _full_package_version="$(get_full_package_version_zypper "${package}" "${version}")" | |
| # Unfortunately, zypper doesn't support `info` command for specific package version | |
| # so let's use dirty hack by downloading the rpm file and find out the dependency | |
| ${SH_C} "zypper install --force --download-only --no-confirm ${package}-${_full_package_version}" &> /dev/null | |
| local _file_package_version | |
| _file_package_version="${_full_package_version##*:}" | |
| find /var/cache/zypp/packages/ -name "${package}-${_file_package_version}"'*.rpm' -exec rpm -qR -p {} \; \ | |
| | awk '$1 == "'"${dep_package}"'" {print $3}' | |
| } | |
| get_dep_package_version(){ | |
| local package="${1:?Please specify package name}" | |
| local version="${2:?Please specify package version}" | |
| local dep_package="${3:?Please specify dependance package name}" | |
| case "${DIST_ID}" in | |
| ubuntu) | |
| get_dep_package_version_deb "${package}" "${version}" "${dep_package}" | |
| ;; | |
| centos | rhel | rocky | amzn | ol) | |
| get_dep_package_version_yum "${package}" "${version}" "${dep_package}" | |
| ;; | |
| sles | opensuse-leap) | |
| get_dep_package_version_zypper "${package}" "${version}" "${dep_package}" | |
| ;; | |
| esac | |
| } | |
| function get_package_epoch() { | |
| local package="${1:?Please specify package name}" | |
| local dist_id="${2:?Please specify dist_id}" | |
| case "${dist_id}" in | |
| ubuntu) | |
| declare -A _deb_package_epoch_map=( | |
| ["docker-ee"]="5:" | |
| ["docker-ee-cli"]="5:" | |
| ["docker-ee-rootless-extras"]="5:" | |
| ["containerd.io"]="" | |
| ) | |
| echo "${_deb_package_epoch_map[${package}]}" | |
| ;; | |
| esac | |
| } | |
| get_full_package_version_deb () { | |
| local package="${1:?Please specify package name}" | |
| local version="${2:?Please specify package version}" | |
| local _epoch | |
| _epoch="$(get_package_epoch "${package}" "${DIST_ID}")" | |
| apt-cache show "${package}=${_epoch}${version}"'*' \ | |
| | awk '$1 == "Version:" {print $2}' | |
| } | |
| get_full_package_version_yum () { | |
| local package="${1:?Please specify package name}" | |
| local version="${2:?Please specify package version}" | |
| local _repoquery=repoquery | |
| command_exists dnf && _repoquery="dnf repoquery" | |
| local _full_version | |
| _full_version="$( ${_repoquery} -q --repoid=docker-ee-"${CHANNEL}" --qf='%{evr}' "${package}-${version}"'*' )" | |
| echo "${_full_version#*:}" | |
| } | |
| get_full_package_version_zypper () { | |
| local package="${1:?Please specify package name}" | |
| local version="${2:?Please specify package version}" | |
| # Unfortunately, zypper doesn't support `info` command for specific package version | |
| # so let's use `zypper search` command which returns a sorted list of versions | |
| #S | Name | Type | Version | Arch | Repository | |
| #--+-----------+---------+-------------------------+--------+--------------- | |
| # | docker-ee | package | 3:23.0.15-3 | x86_64 | docker-ee-test | |
| # | docker-ee | package | 3:23.0.15-2.1.rc1 | x86_64 | docker-ee-test | |
| # | docker-ee | package | 3:23.0.15-0.1.tp1 | x86_64 | docker-ee-test | |
| ${SH_C} "zypper search --match-exact --details --type package ${package}" \ | |
| | gawk -v version="${version##*:}" 'index(gensub(/^[[:digit:]]+:/, "", 1, $4), version) == 1 {print $4; exit}' FS='[[:space:]]+\\|[[:space:]]+' | |
| } | |
| get_full_package_version() { | |
| local package="${1:?Please specify package name}" | |
| local version="${2:?Please specify package version}" | |
| case "${DIST_ID}" in | |
| ubuntu) | |
| get_full_package_version_deb "${package}" "${version}" | |
| ;; | |
| centos | rhel | rocky | amzn | ol) | |
| get_full_package_version_yum "${package}" "${version}" | |
| ;; | |
| sles | opensuse-leap) | |
| get_full_package_version_zypper "${package}" "${version}" | |
| ;; | |
| esac | |
| } | |
| get_docker_c8d_dep() { | |
| local version=${1:?"Please specify docker version"} | |
| local c8d_dep | |
| c8d_dep="$(get_dep_package_version "${DOCKER_PACKAGE_NAME}" "${version}" "${CONTAINERD_PACKAGE_NAME}")" | |
| get_full_package_version "${CONTAINERD_PACKAGE_NAME}" "${c8d_dep}" | |
| } | |
| get_c8d_mapped_version() { | |
| local mcr_ver=${1:-MCR_MAIN_VERSION} | |
| declare -rA _mcr_c8d_deb_map=( | |
| ["23.0.1"]="1.6.17" | |
| ["23.0.3"]="1.6.19" | |
| ["23.0.5"]="1.6.20" | |
| ["23.0.6"]="1.6.21" | |
| ["23.0.7"]="1.6.22" | |
| ["23.0.8"]="1.6.25~rc.1-1" | |
| ["23.0.9"]="1.6.28~rc.1-1" | |
| ["23.0.9-1"]="1.6.28~rc.1-2" | |
| ['23.0.10']="1.6.30~rc.2-1" | |
| ['23.0.13']="1.6.32" | |
| ['23.0.14']="1.6.33" | |
| ) | |
| declare -rA _mcr_c8d_rpm_map=( | |
| ["23.0.1"]="1.6.17" | |
| ["23.0.3"]="1.6.19" | |
| ["23.0.5"]="1.6.20" | |
| ["23.0.6"]="1.6.21" | |
| ["23.0.7"]="1.6.22" | |
| ["23.0.8"]="1.6.25-2.1.rc.1.1" | |
| ["23.0.9"]="1.6.28-2.1.rc.1.1" | |
| ["23.0.9-1"]="1.6.28-3.1.rc.1.1" | |
| ["23.0.10"]="1.6.30-2.2.rc.2.1" | |
| ['23.0.13']="1.6.32" | |
| ['23.0.14']="1.6.33" | |
| ) | |
| local _c8d_ver | |
| case "${DIST_ID}" in | |
| ubuntu) | |
| _c8d_ver="${_mcr_c8d_deb_map["${mcr_ver}"]}" | |
| ;; | |
| centos | rhel | rocky | amzn | ol | sles | opensuse-leap) | |
| _c8d_ver="${_mcr_c8d_rpm_map["${mcr_ver}"]}" | |
| ;; | |
| esac | |
| if [ -z "${_c8d_ver}" ]; then | |
| return 1 | |
| fi | |
| echo "${_c8d_ver}" | |
| } | |
| get_docker_mapped_version() { | |
| local mcr_version="${1:-MCR_MAIN_VERSION}" | |
| declare -rA mcr_docker_deb_map=( | |
| ["23.0.9"]="23.0.9~3-" | |
| ["23.0.9-1"]="23.0.9~4" | |
| ) | |
| declare -rA mcr_docker_rpm_map=( | |
| ["23.0.9"]="23.0.9-3" | |
| ["23.0.9-1"]="23.0.9-4" | |
| ) | |
| local _docker_ver | |
| case "$DIST_ID" in | |
| ubuntu) | |
| _docker_ver=${mcr_docker_deb_map[${mcr_version}]} | |
| ;; | |
| centos | rhel | rocky | amzn | ol | sles | opensuse-leap) | |
| _docker_ver=${mcr_docker_rpm_map[${mcr_version}]} | |
| ;; | |
| esac | |
| if [ -n "${_docker_ver}" ]; then | |
| echo "${_docker_ver}" | |
| fi | |
| } | |
| get_docker_package_version() { | |
| local mcr_version="${1:-MCR_MAIN_VERSION}" | |
| mcr_ver "${mcr_version}" | |
| local _main_version=${BASH_REMATCH[1]} | |
| local _prerelease_designator=${BASH_REMATCH[5]} | |
| local _build_version=${BASH_REMATCH[6]} | |
| local _prerelease="${_prerelease_designator}${_build_version}" | |
| local _ver | |
| _ver="$(get_docker_mapped_version "${mcr_version}")" | |
| if [ -n "${_ver}" ]; then | |
| echo "${_ver}" | |
| return 0 | |
| fi | |
| case "${DIST_ID}" in | |
| ubuntu) | |
| # the first number after the tilde corresponds to the prerelease | |
| # designator. for tp, it's 0, for rc, it's 2, and for release, it's 3. | |
| # build_version does not appear in prerelease versions, we ignore it. | |
| case "${_prerelease_designator}" in | |
| tp) | |
| echo "${_main_version}~0.${_build_version}.${_prerelease}" | |
| ;; | |
| rc) | |
| echo "${_main_version}~2.${_build_version}.${_prerelease}" | |
| ;; | |
| *) | |
| echo "${_main_version}~$(( 3 + _build_version ))" | |
| ;; | |
| esac | |
| ;; | |
| centos | rhel | rocky | amzn | ol) | |
| case "${_prerelease_designator}" in | |
| tp) | |
| echo "${_main_version}-0.${_build_version}.${_prerelease}." | |
| ;; | |
| rc) | |
| echo "${_main_version}-2.${_build_version}.${_prerelease}." | |
| ;; | |
| *) | |
| echo "${_main_version}-$(( 3 + _build_version ))." | |
| ;; | |
| esac | |
| ;; | |
| sles | opensuse-leap) | |
| # On zypper-based systems version terminates before any extra fluffy | |
| # bits, which means we can't end our search string (the thing we're | |
| # making here) with a dot. This means that, on zipper, we might match | |
| # both build version 29 (which ends in -30) and build version 0 (which | |
| # ends in -3). If we ever have 30 build versions, we can fix this. | |
| case "${_prerelease_designator}" in | |
| tp) | |
| echo "${_main_version}-0.${_build_version}.${_prerelease}" | |
| ;; | |
| rc) | |
| echo "${_main_version}-2.${_build_version}.${_prerelease}" | |
| ;; | |
| *) | |
| echo "${_main_version}-$(( 3 + _build_version ))" | |
| ;; | |
| esac | |
| ;; | |
| esac | |
| } | |
| get_c8d_version() { | |
| local mcr_ver=${1:?Please specify MCR package version} | |
| local docker_ver=${2:?Please specify docker package version} | |
| if [ -n "${CONTAINERD_VERSION}" ]; then | |
| echo "${CONTAINERD_VERSION}" | |
| return 0 | |
| fi | |
| get_c8d_mapped_version "${mcr_ver}" || get_docker_c8d_dep "${docker_ver}" | |
| } | |
| get_c8d_package_version() { | |
| local mcr_ver=${1:?Please specify MCR package version} | |
| local docker_ver=${2:?Please specify docker package version} | |
| get_full_package_version "${CONTAINERD_PACKAGE_NAME}" "$(get_c8d_version "${mcr_ver}" "${docker_ver}")" | |
| } | |
| command_exists() { | |
| command -v "$@" > /dev/null 2>&1 | |
| } | |
| on_ec2() { | |
| [ -f /sys/hypervisor/uuid ] && [ "$(head -c 3 /sys/hypervisor/uuid)" == ec2 ] | |
| } | |
| strip_trailing_slash() { | |
| echo "${1/%\/}" | |
| } | |
| # version_gte checks if the version specified in $VERSION is at least | |
| # the given CalVer (YY.MM) version. returns 0 (success) if $VERSION is either | |
| # unset (=latest) or newer or equal than the specified version. Returns 1 (fail) | |
| # otherwise. | |
| # | |
| # examples: | |
| # | |
| # VERSION=20.10 | |
| # version_gte 20.10 // 0 (success) | |
| # version_gte 19.03 // 0 (success) | |
| # version_gte 21.10 // 1 (fail) | |
| version_gte() { | |
| if [ -z "$VERSION" ]; then | |
| return 0 | |
| fi | |
| calver_compare "${VERSION%%-*}" "$1" | |
| } | |
| # calver_compare compares two CalVer (YY.MM.VER) version strings. returns 0 (success) | |
| # if version A is newer or equal than version B, or 1 (fail) otherwise. Patch | |
| # releases and pre-release (-alpha/-beta) are not taken into account | |
| # | |
| # examples: | |
| # | |
| # calver_compare 20.10.12 19.03 // 0 (success) | |
| # calver_compare 20.10.12 20.10.12 // 0 (success) | |
| # calver_compare 19.03.02 20.10.12 // 1 (fail) | |
| calver_compare() ( | |
| set +x | |
| yy_a="$(echo "$1" | cut -d'.' -f1)" | |
| yy_b="$(echo "$2" | cut -d'.' -f1)" | |
| if (( "$yy_a" < "$yy_b" )); then | |
| return 1 | |
| fi | |
| if (( "$yy_a" > "$yy_b" )); then | |
| return 0 | |
| fi | |
| mm_a="$(echo "$1" | cut -d'.' -f2)" | |
| mm_b="$(echo "$2" | cut -d'.' -f2)" | |
| if (( "${mm_a}" < "${mm_b}" )); then | |
| return 1 | |
| fi | |
| ver_a="$(echo "$1" | cut -d'.' -f3)" | |
| ver_b="$(echo "$2" | cut -d'.' -f3)" | |
| if (( "$ver_a" < "$ver_b" )); then | |
| return 1 | |
| fi | |
| return 0 | |
| ) | |
| ubuntu_prepare() { | |
| declare -rx DEBIAN_FRONTEND=noninteractive | |
| if [[ -n "${SKIP_REPO_SETUP}" ]]; then | |
| return | |
| fi | |
| local _pre_reqs="apt-transport-https ca-certificates curl software-properties-common" | |
| if ! command -v gpg > /dev/null; then | |
| _pre_reqs="$_pre_reqs gnupg" | |
| fi | |
| ( | |
| set -ex | |
| ${SH_C} "apt-get update -qq" | |
| ${SH_C} "apt-get install -y -qq $_pre_reqs" &>/dev/null | |
| ) | |
| local _ubuntu_url | |
| _ubuntu_url=$(strip_trailing_slash "${DOCKER_URL}") | |
| # Check if we have a gpg (should be valid repo to use if it's there) before appending suffix | |
| if ! curl -fsSL "${_ubuntu_url}/gpg" >/dev/null; then | |
| # URL's may not be suffixed with ubuntu, let's make sure that they are | |
| if [[ ! "${_ubuntu_url}" =~ /ubuntu$ ]]; then | |
| _ubuntu_url="${_ubuntu_url}/ubuntu" | |
| fi | |
| fi | |
| local _arch | |
| _arch="$(dpkg --print-architecture)" | |
| # Grab this outside of the command to install, so it's not muddled | |
| local _release | |
| # shellcheck disable=SC1091 | |
| _release="$(. /etc/os-release && echo "${VERSION_CODENAME}")" | |
| ( | |
| set -ex | |
| curl -fsSL "${_ubuntu_url}"/gpg | ${SH_C} "apt-key add -qq -" >/dev/null | |
| ${SH_C} "add-apt-repository -y 'deb [arch=${_arch}] ${_ubuntu_url} ${_release} ${CHANNEL}'" >/dev/null | |
| ${SH_C} "apt-get update -qq" >/dev/null | |
| ) | |
| } | |
| ubuntu_install() { | |
| declare -rx DEBIAN_FRONTEND=noninteractive | |
| local docker_version="${1:?Specify docker version}" | |
| ubuntu_prepare | |
| local _docker_package="${DOCKER_PACKAGE_NAME}" | |
| # By default, don't include a cli_package and rootless_package to install just let the package manager grab the topmost one | |
| local _cli_package="${DOCKER_CLI_PACKAGE_NAME}" | |
| local _rootless_package="${DOCKER_ROOTLESS_PACKAGE_NAME}" | |
| local _containerd_package="${CONTAINERD_PACKAGE_NAME}" | |
| local _docker_package_version | |
| _docker_package_version="$(get_full_package_version "${_docker_package}" "${docker_version}")" | |
| local _cli_package_version | |
| _cli_package_version="$(get_full_package_version "${_cli_package}" "${docker_version}")" | |
| local _rootless_package_version | |
| if version_gte "${MIN_ROOTLESS_VER}"; then | |
| _rootless_package_version="$(get_full_package_version "${_rootless_package}" "${docker_version}")" | |
| fi | |
| echo "INFO: Searching repository for Docker package VERSION '${docker_version}'" | |
| if [ -z "${_docker_package_version}" ]; then | |
| echo | |
| echo "ERROR: '${docker_version}' not found amongst apt-cache madison results" | |
| echo | |
| exit 1 | |
| fi | |
| # If a cli package was found for the given version then include it in the installation | |
| if [ -n "${_cli_package_version}" ]; then | |
| _cli_package+="=${_cli_package_version}" | |
| fi | |
| # If a rootless package was found for the given version then include it in the installation | |
| if [ -n "$_rootless_package_version" ]; then | |
| _rootless_package+="=${_rootless_package_version}" | |
| fi | |
| _docker_package+="=${_docker_package_version}" | |
| if version_gte "$MIN_MCR_WITH_C8D_VER"; then | |
| local _c8d_version | |
| _c8d_version="$(get_c8d_package_version "${MCR_MAIN_VERSION}" "${_docker_package_version}")" | |
| if [ -n "${_c8d_version}" ]; then | |
| _containerd_package+="=${_c8d_version}" | |
| fi | |
| fi | |
| ( | |
| local _apt_flags="-y -qq --allow-downgrades ${DRY_RUN:+ --dry-run}" | |
| set -ex | |
| ${SH_C} "apt-get install ${_apt_flags} ${_docker_package} ${_cli_package} ${_rootless_package} ${_containerd_package}" | |
| ) | |
| } | |
| yum_prepare() { | |
| local dist_id="${1:?Specify Distribution Id}" | |
| local dist_version="${2:?Please specify Distribution version}" | |
| if [[ -n "${SKIP_REPO_SETUP}" ]]; then | |
| return | |
| fi | |
| local _yum_url | |
| _yum_url=$(strip_trailing_slash "${DOCKER_URL}") | |
| ( | |
| set -ex | |
| command_exists curl || ${SH_C} 'yum install -q -y curl' | |
| ) | |
| # Check if we have a usable repo file before appending suffix | |
| if ! curl --fail --silent --location --head "${_yum_url}/docker-ee.repo" >/dev/null; then | |
| if [[ ! "${_yum_url}" =~ /centos$|/rhel$|rocky$ ]]; then | |
| _yum_url="${_yum_url}/${dist_id}" | |
| fi | |
| fi | |
| case ${dist_id}:${dist_version} in | |
| oraclelinux:7*) | |
| # Enable "Oracle Linux 7 Server Add ons (x86_64)" repo for oraclelinux7 | |
| ( | |
| set -ex | |
| ${SH_C} 'yum-config-manager --enable ol7_addons' | |
| ) | |
| ;; | |
| rhel:7*) | |
| local _extras_repo="rhel-7-server-extras-rpms" | |
| if on_ec2; then | |
| ${SH_C} "yum install -y rh-amazon-rhui-client" | |
| _extras_repo="rhel-7-server-rhui-extras-rpms" | |
| fi | |
| # We don't actually make packages for 7.1, but they can still use the 7 repository | |
| if [ "${dist_version}" = "7.1" ]; then | |
| dist_version="7" | |
| fi | |
| # Enable extras repo for rhel | |
| ( | |
| set -ex | |
| ${SH_C} "yum-config-manager --enable ${_extras_repo}" | |
| ) | |
| ;; | |
| esac | |
| ( | |
| set -ex | |
| ${SH_C} "echo '${_yum_url}' > /etc/yum/vars/dockerurl" | |
| ${SH_C} "echo '${dist_version}' > /etc/yum/vars/dockerosversion" | |
| ${SH_C} "yum install -q -y yum-utils device-mapper-persistent-data lvm2" | |
| ${SH_C} "yum-config-manager --add-repo ${_yum_url}/docker-ee.repo" | |
| ${SH_C} "yum-config-manager --disable 'docker-ee-*'" | |
| ${SH_C} "yum-config-manager --enable 'docker-ee-${CHANNEL}'" | |
| ) | |
| } | |
| yum_install() { | |
| local docker_version="${1:?Specify docker version}" | |
| local dist_id="${2:?Specify Distribution Id}" | |
| local dist_version="${3:?Please specify Distribution version}" | |
| yum_prepare "${dist_id}" "${dist_version}" | |
| local _docker_package="${DOCKER_PACKAGE_NAME}" | |
| # By default, don't include a cli_package and rootless_package to install just let the package manager grab the topmost one | |
| local _cli_package="${DOCKER_CLI_PACKAGE_NAME}" | |
| local _rootless_package="" | |
| local _containerd_package="${CONTAINERD_PACKAGE_NAME}" | |
| local _docker_package_version | |
| _docker_package_version="$(get_full_package_version "${_docker_package}" "${docker_version}")" | |
| local _cli_package_version | |
| _cli_package_version="$(get_full_package_version "${_cli_package}" "${docker_version}")" | |
| local _rootless_package_version | |
| if version_gte "$MIN_ROOTLESS_VER" && [ "${dist_id}:${dist_version}" != "oraclelinux:7" ]; then | |
| # like the CLI, rootless-extras packages don't start with 3:. They don't | |
| # start with anything, actually. | |
| _rootless_package="${DOCKER_ROOTLESS_PACKAGE_NAME}" | |
| _rootless_package_version="$(get_full_package_version "${_rootless_package}" "${docker_version}")" | |
| fi | |
| echo "INFO: Searching repository for Docker package VERSION '${docker_version}'" | |
| if [ -z "${_docker_package_version}" ]; then | |
| echo | |
| echo "ERROR: '${docker_version}' not found amongst yum list results" | |
| echo | |
| exit 1 | |
| fi | |
| if [ -n "$_cli_package_version" ]; then | |
| _cli_package+="-${_cli_package_version}" | |
| fi | |
| if [ -n "$_rootless_package_version" ]; then | |
| _rootless_package+="-${_rootless_package_version}" | |
| fi | |
| _docker_package+="-${_docker_package_version}" | |
| local _yum_cmd="install" | |
| # Check if we're doing an upgrade / downgrade and the command accordingly | |
| echo "INFO: Checking to determine whether this should be an upgrade or downgrade" | |
| # If the package isn't really installed then don't try upgrade / downgrade | |
| if ! yum list installed "${DOCKER_PACKAGE_NAME}" >/dev/null; then | |
| _yum_cmd="install" | |
| # Exit codes when using --assumeno will give 0 if there would be an upgrade/downgrade, 1 if there is | |
| elif ! ${SH_C} "yum upgrade --assumeno ${_docker_package}"; then | |
| _yum_cmd="upgrade" | |
| elif ! ${SH_C} "yum downgrade --assumeno ${_docker_package}"; then | |
| _yum_cmd="downgrade" | |
| fi | |
| local _c8d_version | |
| echo "INFO: will use install command $_yum_cmd" | |
| if version_gte "$MIN_MCR_WITH_C8D_VER"; then | |
| _c8d_version="$(get_c8d_package_version "${MCR_MAIN_VERSION}" "${_docker_package_version}")" | |
| if [ -n "${_c8d_version}" ]; then | |
| _containerd_package+="-${_c8d_version}" | |
| fi | |
| fi | |
| ( | |
| local _yum_flags="-q" | |
| if [ -n "${DRY_RUN}" ]; then | |
| _yum_flags+=" --assumeno" | |
| else | |
| _yum_flags+=" --assumeyes" | |
| fi | |
| set -ex | |
| ${SH_C} "yum ${_yum_cmd} ${_yum_flags} ${_docker_package} ${_cli_package} ${_rootless_package} ${_containerd_package}" | |
| ) | |
| } | |
| REPO_VERSION="" | |
| zypper_prepare() { | |
| if [[ -n "${SKIP_REPO_SETUP}" ]]; then | |
| return | |
| fi | |
| local _arch | |
| _arch="$(uname -m)" | |
| ( | |
| set -ex | |
| ${SH_C} "zypper install --no-confirm curl gawk" | |
| ) | |
| local _zypper_url | |
| _zypper_url=$(strip_trailing_slash "${DOCKER_URL}") | |
| # No need to append sles if we already have a valid repo | |
| if ! curl -fsL "${_zypper_url}/docker-ee.repo" >/dev/null; then | |
| _zypper_url="${_zypper_url}/sles" | |
| fi | |
| ( | |
| set -ex | |
| # SLES images have installed Docker CE by default, which conflicts w/ MCR, so it needs to be deleted | |
| ${SH_C} "zypper remove -y docker docker-engine docker-libnetwork runc containerd" || true | |
| ${SH_C} "zypper removerepo docker-ee-${CHANNEL}" # this will always return 0 even if repo alias not found | |
| ${SH_C} "zypper addrepo ${_zypper_url}/${REPO_VERSION}/${_arch}/${CHANNEL} docker-ee-${CHANNEL}" | |
| ${SH_C} "rpm --import '${_zypper_url}/gpg'" | |
| ${SH_C} "zypper refresh" | |
| ) | |
| } | |
| zypper_install() { | |
| local docker_version="${1:?Specify docker version}" | |
| local dist_version="${2}" | |
| REPO_VERSION=15 | |
| zypper_prepare | |
| local _docker_package="${DOCKER_PACKAGE_NAME}" | |
| # By default, don't include a cli_package and _rootless_package to install just let the package manager grab the topmost one | |
| local _cli_package="${DOCKER_CLI_PACKAGE_NAME}" | |
| local _rootless_package="" | |
| local _containerd_package="${CONTAINERD_PACKAGE_NAME}" | |
| local _docker_package_version | |
| _docker_package_version="$(get_full_package_version "${_docker_package}" "${docker_version}")" | |
| local _cli_package_version | |
| _cli_package_version="$(get_full_package_version "${_cli_package}" "${docker_version}")" | |
| local _rootless_package_version | |
| if version_gte "${MIN_ROOTLESS_VER}"; then | |
| _rootless_package="${DOCKER_ROOTLESS_PACKAGE_NAME}" | |
| _rootless_package_version="$(get_full_package_version "${_rootless_package}" "${docker_version}")" | |
| fi | |
| echo "INFO: Searching repository for VERSION '${docker_version}'" | |
| if [ -z "${_docker_package_version}" ]; then | |
| echo | |
| echo "ERROR: '${docker_version}' not found amongst zypper search results" | |
| echo | |
| exit 1 | |
| fi | |
| # If a cli package was found for the given version then include it in the installation | |
| if [ -n "${_cli_package_version}" ]; then | |
| _cli_package+="-${_cli_package_version}" | |
| fi | |
| # If a rootless package was found for the given version then include it in the installation | |
| if [ -n "${_rootless_package_version}" ]; then | |
| _rootless_package+="-${_rootless_package_version}" | |
| fi | |
| _docker_package+="-${_docker_package_version}" | |
| local _c8d_version | |
| if version_gte "$MIN_MCR_WITH_C8D_VER"; then | |
| _c8d_version="$(get_c8d_package_version "${MCR_MAIN_VERSION}" "${_docker_package_version}")" | |
| if [ -n "${_c8d_version}" ]; then | |
| _containerd_package+="-${_c8d_version}" | |
| fi | |
| fi | |
| ( | |
| local _zypper_flags="--replacefiles --force --no-confirm --allow-vendor-change" | |
| if [ -n "${DRY_RUN}" ]; then | |
| _zypper_flags+=" --dry-run" | |
| fi | |
| set -ex | |
| ${SH_C} "zypper install ${_zypper_flags} ${_docker_package} ${_cli_package} ${_rootless_package} ${_containerd_package}" | |
| ) | |
| } | |
| is_fips_enabled(){ | |
| # if FIPS is enabled on the OS | |
| local fips | |
| fips=$(cat /proc/sys/crypto/fips_enabled) | |
| (( fips > 0 )) && return 0 | |
| # FIPS isn't enabled | |
| return 1 | |
| } | |
| get_channel() { | |
| declare -r DEFAULT_NONFIPS_EE_CHANNEL="stable-25.0" | |
| declare -r DEFAULT_FIPS_EE_CHANNEL="${DEFAULT_NONFIPS_EE_CHANNEL}/fips" | |
| # if CHANNEL is set, use it | |
| [[ -n "${CHANNEL}" ]] && echo "${CHANNEL}" && return 0 | |
| # if FIPS is enabled in kernel, use the FIPS channel | |
| is_fips_enabled && echo "${DEFAULT_FIPS_EE_CHANNEL}" || echo "${DEFAULT_NONFIPS_EE_CHANNEL}" | |
| } | |
| install_mcr_packages() { | |
| local install_cmd="${1:?Please specify install command}" | |
| local docker_package="${DOCKER_PACKAGE_NAME}" | |
| local cli_package="${DOCKER_CLI_PACKAGE_NAME}" | |
| local rootless_package="${DOCKER_ROOTLESS_PACKAGE_NAME}" | |
| local containerd_package="${CONTAINERD_PACKAGE_NAME}" | |
| # TODO(dperny): make configurable, in a sane way. | |
| local cri_package="${CRI_DOCKERD_PACKAGE_NAME}" | |
| local runc_package="${RUNC_PACKAGE_NAME}" | |
| local additional_runtimes | |
| if [ -n "${ADDITIONAL_RUNTIMES}" ]; then | |
| local _runtimes | |
| _runtimes=$(echo "${ADDITIONAL_RUNTIMES}" | tr ',' ' ') | |
| local _runtime | |
| for _runtime in $_runtimes; do | |
| additional_runtimes+="containerd.io-${_runtime} " | |
| done | |
| fi | |
| ( | |
| set -ex | |
| # Just do the full install, with all required packages. | |
| $SH_C "${install_cmd} ${docker_package} ${cli_package} ${rootless_package} ${containerd_package} ${cri_package} ${runc_package} ${additional_runtimes}" | |
| ) | |
| } | |
| ubuntu_prepare_25() { | |
| declare -rx DEBIAN_FRONTEND=noninteractive | |
| if [ -n "${SKIP_REPO_SETUP}" ]; then | |
| return | |
| fi | |
| ( | |
| set -ex | |
| $SH_C "apt-get update -qq" | |
| $SH_C "apt-get install -y -qq curl gnupg" >/dev/null | |
| ) | |
| local component | |
| component="$(get_channel)" | |
| # Download the keyring to the package-updateable location as described | |
| # in https://wiki.debian.org/DebianRepository/UseThirdParty | |
| # and configure APT to trust it only for our source's entry. | |
| local keyring="/usr/share/keyrings/mirantis-archive-keyring.pgp" | |
| local ubuntu_url | |
| ubuntu_url="${DOCKER_URL%/}" | |
| local keyring_asc | |
| if ! keyring_asc="$(curl -fsSL "$ubuntu_url/gpg")" 2>/dev/null; then | |
| # URL's may not be suffixed with ubuntu, let's make sure that they are | |
| if [[ "$ubuntu_url" != */ubuntu$ ]]; then | |
| ubuntu_url+="/ubuntu" | |
| keyring_asc="$(curl -fsSL "$ubuntu_url/gpg")" | |
| fi | |
| fi | |
| ( | |
| set -ex | |
| $SH_C "gpg --batch --yes --output '${keyring}' --dearmor" <<< "$keyring_asc" | |
| # Add the apt repository for 25.0 in general | |
| # shellcheck source=/dev/null | |
| $SH_C 'tee /etc/apt/sources.list.d/mirantis.sources' <<< "\ | |
| Types: deb | |
| URIs: $ubuntu_url | |
| Suites: $(. /etc/os-release && echo "$VERSION_CODENAME") | |
| Components: $component | |
| Architectures: $(dpkg --print-architecture) | |
| Signed-By: $keyring" | |
| $SH_C "apt-get update -qq" | |
| ) | |
| } | |
| ubuntu_install_25() { | |
| declare -rx DEBIAN_FRONTEND=noninteractive | |
| ubuntu_prepare_25 | |
| install_mcr_packages "apt-get install -y -qq" | |
| } | |
| yum_prepare_25() { | |
| local DIST_ID="$1" | |
| if [[ -n "${SKIP_REPO_SETUP}" ]]; then | |
| return | |
| fi | |
| # unlike ubuntu, with yum and RPMs, we install based on a specific URL. | |
| local yum_url | |
| yum_url="${DOCKER_URL%/}" | |
| local component | |
| component="$(get_channel)" | |
| command -v curl &> /dev/null || ( | |
| set -ex | |
| $SH_C "dnf install -q -y curl" | |
| ) | |
| # Check if we have a usable repo file before appending suffix | |
| if ! curl --head -fsSL "$yum_url/gpg" &>/dev/null; then | |
| if [[ ! "$yum_url" =~ /centos$|/rhel$|rocky$ ]]; then | |
| yum_url+="/$DIST_ID" | |
| fi | |
| fi | |
| # Add a repository for 25.0 in general | |
| ( | |
| set -ex | |
| $SH_C 'tee /etc/yum.repos.d/docker-ee.repo' <<< "[mirantis] | |
| name=Mirantis Container Runtime | |
| baseurl=$yum_url/\$releasever/\$basearch/$component | |
| enabled=1 | |
| gpgcheck=1 | |
| gpgkey=$yum_url/gpg | |
| module_hotfixes=true" | |
| ) | |
| } | |
| yum_install_25() { | |
| local DIST_ID="$1" | |
| yum_prepare_25 "${DIST_ID}" | |
| install_mcr_packages "dnf install -q -y" | |
| } | |
| zypper_prepare_25() { | |
| local dist_version | |
| dist_version=$1 | |
| if [[ -n "${SKIP_REPO_SETUP}" ]]; then | |
| return | |
| fi | |
| local arch | |
| arch="$(uname -m)" | |
| local component | |
| component="$(get_channel)" | |
| local repo_version="${dist_version%%.*}" | |
| # Check if we have curl. If not, we need it. | |
| command -v curl &> /dev/null || ( | |
| set -ex | |
| $SH_C "zypper install -y curl" | |
| ) | |
| local zypper_url | |
| zypper_url="${DOCKER_URL%/}" | |
| # no need to append sles if we already have a valid repo | |
| if ! curl -fsL "$zypper_url/gpg" >/dev/null; then | |
| zypper_url+="/sles" | |
| fi | |
| ( | |
| set -ex | |
| # you do, in fact, need to removerepo, or running this script a second | |
| # time on a box will fail (even if you've uninstalled in the meantime, | |
| # unless your uninstallation involved doing this command) | |
| $SH_C "zypper removerepo mirantis" # this will always return 0 even if repo alias not found | |
| $SH_C "zypper addrepo $zypper_url/$repo_version/$arch/$component mirantis" | |
| $SH_C "rpm --import '$zypper_url/gpg'" | |
| $SH_C "zypper refresh" | |
| ) | |
| } | |
| zypper_install_25() { | |
| local dist_version | |
| dist_version=$1 | |
| zypper_prepare_25 "${dist_version}" | |
| install_mcr_packages "zypper install --allow-vendor-change --allow-downgrade --no-confirm -y" | |
| } | |
| unsupported_os() { | |
| local _dist_id="${1?-Please specify Distribution Id}" | |
| local _dist_version="${2?-Please specify Distribution version}" | |
| echo | |
| echo "ERROR: Unsupported distribution / distribution version '${_dist_id}:${_dist_version}'" | |
| echo " If you feel this is a mistake please contact Mirantis support" | |
| echo | |
| exit 1 | |
| } | |
| main() { | |
| local _user | |
| _user="$(id -un 2>/dev/null || true)" | |
| if [ "${_user}" != 'root' ]; then | |
| if command_exists sudo; then | |
| SH_C='sudo -E sh -c' | |
| elif command_exists su; then | |
| SH_C='su -c' | |
| else | |
| cat >&2 <<-'EOF' | |
| Error: this installer needs the ability to run commands as root. | |
| We are unable to find either "sudo" or "su" available to make this happen. | |
| EOF | |
| exit 1 | |
| fi | |
| fi | |
| # shellcheck disable=SC1091 | |
| DIST_ID="$(. /etc/os-release && echo "$ID")" | |
| local _dist_version | |
| # shellcheck disable=SC1091 | |
| _dist_version="$(. /etc/os-release && echo "$VERSION_ID")" | |
| if [ -z "${DOCKER_URL}" ]; then | |
| echo "ERROR: DOCKER_URL must be set, exiting..." | |
| exit 1 | |
| fi | |
| if ! mcr_ver "${VERSION}" && [[ "${VERSION/.*}" -lt 25 ]]; then | |
| echo "${VERSION} doesn't match with expected pattern. Version must follow this pattern a.b.c, a.b.c-d, a.b.c-(tp|rc)e, a.b.c-d-(tp|rc)e, where a,b,c,d,e are numbers." | |
| exit 1 | |
| fi | |
| MCR_MAIN_VERSION="${BASH_REMATCH[1]}${BASH_REMATCH[2]}" | |
| local _docker_pkg_ver | |
| _docker_pkg_ver="$(get_docker_package_version "${VERSION}")" | |
| case "$DIST_ID:$_dist_version" in | |
| ubuntu:20.04|ubuntu:22.04) | |
| # TODO(dperny): All of this checking to see if the version is 25.0 isn't | |
| # really future-proof, because what about 25.1? But that's tomorrow's | |
| # problem. | |
| if [[ "${VERSION/.*}" -ge 25 ]]; then | |
| ubuntu_install_25 | |
| else | |
| ubuntu_install "${_docker_pkg_ver}" | |
| fi | |
| exit 0 | |
| ;; | |
| ubuntu:24.04) | |
| if [[ "${VERSION/.*}" -ge 25 ]]; then | |
| ubuntu_install_25 | |
| else | |
| unsupported_os "${DIST_ID}" "${_dist_version}" | |
| fi | |
| exit 0 | |
| ;; | |
| centos:*|rhel:*|rocky:*) | |
| # Strip point versions, they don't really matter | |
| if [[ "${VERSION/.*}" -ge 25 ]]; then | |
| yum_install_25 "$DIST_ID" | |
| else | |
| yum_install "${_docker_pkg_ver}" "$DIST_ID" "${_dist_version%%.*}" | |
| fi | |
| exit 0 | |
| ;; | |
| ol:*) | |
| if [[ "${VERSION/.*}" -ge 25 ]]; then | |
| yum_install_25 "oraclelinux" | |
| else | |
| # Consider only major version for OL distros | |
| yum_install "${_docker_pkg_ver}" "oraclelinux" "${_dist_version%%.*}" | |
| fi | |
| exit 0 | |
| ;; | |
| sles:15*|opensuse-leap:15*) | |
| if [[ "${VERSION/.*}" -ge 25 ]]; then | |
| zypper_install_25 "$_dist_version" | |
| else | |
| zypper_install "${_docker_pkg_ver}" "${_dist_version%%.*}" | |
| fi | |
| exit 0 | |
| ;; | |
| *) | |
| unsupported_os "${DIST_ID}" "${_dist_version}" | |
| ;; | |
| esac | |
| } | |
| main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment