Skip to content

Instantly share code, notes, and snippets.

@rleap-m
Created February 27, 2026 15:58
Show Gist options
  • Select an option

  • Save rleap-m/5f023fec27e82a68032de59f2ffdd5a7 to your computer and use it in GitHub Desktop.

Select an option

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
#!/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