Unverified Commit 30e03b62 authored by Jeff Putsch's avatar Jeff Putsch Committed by GitHub

Add RHEL support to the python feature (#830)

* install gpg2.22 on centos 7 when installing python

* RHEL support, exisiting tests pass, new RHEL tests pass.

* add tests, cleanup install organization

* update testing to include RHEL tests

* update testing to include RHEL tests

* undo addition of installing additional pip modules

* fix errors installing os-provided Python on recent Debian systems and on Mariner systems

* adjust to properly use newly installed python (PYTHON_SRC) instead of assuming "python" will work

* When installing pipx, check if python is marked as externally
managed. If so, add "--break-system-packages" to the pip install
flags.

This does not really breack system packages due to the setting of
PYTHONUSERBASE during the install of pipx, but does get us past
checks for installing python packages into the system python install.

* merge from main

* update check for managed python install. pass all tests.

* add "packages" option from PR #768

* remove "packages" option

* Address PR feedback, passes all tests locally.

* fix install error on centos

---------
Co-authored-by: 's avatarJeff Putsch <jputsch@analog.com>
parent 1592dd59
......@@ -67,7 +67,7 @@ jobs:
test-scenarios:
needs: [detect-changes]
runs-on: ubuntu-latest
runs-on: devcontainer-image-builder-ubuntu
continue-on-error: true
strategy:
matrix:
......
......@@ -2,6 +2,6 @@
## OS Support
This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed.
This Feature should work on recent versions of Debian/Ubuntu, RedHat Enterprise Linux, Fedora, Alma, and RockyLinux distributions with the apt, yum, dnf, or microdnf package manager installed.
`bash` is required to execute the `install.sh` script.
{
"id": "python",
"version": "1.3.2",
"version": "1.4.0",
"name": "Python",
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/python",
"description": "Installs the provided version of Python, as well as PIPX, and other common Python utilities. JupyterLab is conditionally installed with the python feature. Note: May require source code compilation.",
......@@ -25,13 +25,23 @@
"installTools": {
"type": "boolean",
"default": true,
"description": "Install common Python tools like pylint"
"description": "Flag indicating whether or not to install the tools specified via the 'toolsToInstall' option. Default is 'true'."
},
"toolsToInstall": {
"type": "string",
"default": "flake8,autopep8,black,yapf,mypy,pydocstyle,pycodestyle,bandit,pipenv,virtualenv,pytest,pylint",
"description": "Comma-separated list of tools to install when 'installTools' is true. Defaults to a set of common Python tools like pylint."
},
"optimize": {
"type": "boolean",
"default": false,
"description": "Optimize Python for performance when compiled (slow)"
},
"enableShared": {
"type": "boolean",
"default": false,
"description": "Enable building a shared Python library"
},
"installPath": {
"type": "string",
"default": "/usr/local/python",
......
......@@ -10,6 +10,7 @@
PYTHON_VERSION="${VERSION:-"latest"}" # 'system' or 'os-provided' checks the base image first, else installs 'latest'
INSTALL_PYTHON_TOOLS="${INSTALLTOOLS:-"true"}"
OPTIMIZE_BUILD_FROM_SOURCE="${OPTIMIZE:-"false"}"
ENABLE_SHARED_FROM_SOURCE="${ENABLESHARED:-"false"}"
PYTHON_INSTALL_PATH="${INSTALLPATH:-"/usr/local/python"}"
OVERRIDE_DEFAULT_VERSION="${OVERRIDEDEFAULTVERSION:-"true"}"
......@@ -26,7 +27,10 @@ CONFIGURE_JUPYTERLAB_ALLOW_ORIGIN="${CONFIGUREJUPYTERLABALLOWORIGIN:-""}"
# alongside PYTHON_VERSION, but not set as default.
ADDITIONAL_VERSIONS="${ADDITIONALVERSIONS:-""}"
DEFAULT_UTILS=("pylint" "flake8" "autopep8" "black" "yapf" "mypy" "pydocstyle" "pycodestyle" "bandit" "pipenv" "virtualenv" "pytest")
# Comma-separated list of additional tools to be installed via pipx.
IFS="," read -r -a DEFAULT_UTILS <<< "${TOOLSTOINSTALL:-flake8,autopep8,black,yapf,mypy,pydocstyle,pycodestyle,bandit,pipenv,virtualenv,pytest}"
PYTHON_SOURCE_GPG_KEYS="64E628F8D684696D B26995E310250568 2D347EA6AA65421D FB9921286F5E1540 3A5CA953F73C700D 04C367C218ADD4FF 0EDDC5F26A45C816 6AF053F07D9DC8D2 C9BE28DEE6DF025C 126EB563A74B06BF D9866941EA5BBD71 ED9D77D5 A821E680E5FA6305"
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com
keyserver hkp://keyserver.ubuntu.com:80
......@@ -37,44 +41,90 @@ KEYSERVER_PROXY="${HTTPPROXY:-"${HTTP_PROXY:-""}"}"
set -e
# 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
# Ensure that login shells get the correct path if the user updated the PATH using ENV.
rm -f /etc/profile.d/00-restore-env.sh
echo "export PATH=${PATH//$(sh -lc 'echo $PATH')/\$PATH}" > /etc/profile.d/00-restore-env.sh
chmod +x /etc/profile.d/00-restore-env.sh
# 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
# Bring in ID, ID_LIKE, VERSION_ID, VERSION_CODENAME
. /etc/os-release
# Get an adjusted ID independent of distro variants
MAJOR_VERSION_ID=$(echo ${VERSION_ID} | cut -d . -f 1)
if [ "${ID}" = "debian" ] || [ "${ID_LIKE}" = "debian" ]; then
ADJUSTED_ID="debian"
elif [[ "${ID}" = "rhel" || "${ID}" = "fedora" || "${ID}" = "mariner" || "${ID_LIKE}" = *"rhel"* || "${ID_LIKE}" = *"fedora"* || "${ID_LIKE}" = *"mariner"* ]]; then
ADJUSTED_ID="rhel"
if [[ "${ID}" = "rhel" ]] || [[ "${ID}" = *"alma"* ]] || [[ "${ID}" = *"rocky"* ]]; then
VERSION_CODENAME="rhel${MAJOR_VERSION_ID}"
else
VERSION_CODENAME="${ID}${MAJOR_VERSION_ID}"
fi
done
if [ "${USERNAME}" = "" ]; then
USERNAME=root
else
echo "Linux distro ${ID} not supported."
exit 1
fi
# To find some devel packages, some rhel need to enable specific extra repos, but not on RedHat ubi images...
INSTALL_CMD_ADDL_REPO=""
if [ ${ADJUSTED_ID} = "rhel" ] && [ ${ID} != "rhel" ]; then
if [ ${MAJOR_VERSION_ID} = "8" ]; then
INSTALL_CMD_ADDL_REPOS="--enablerepo powertools"
elif [ ${MAJOR_VERSION_ID} = "9" ]; then
INSTALL_CMD_ADDL_REPOS="--enablerepo crb"
fi
elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then
USERNAME=root
fi
# Setup INSTALL_CMD & PKG_MGR_CMD
if type apt-get > /dev/null 2>&1; then
PKG_MGR_CMD=apt-get
INSTALL_CMD="${PKG_MGR_CMD} -y install --no-install-recommends"
elif type microdnf > /dev/null 2>&1; then
PKG_MGR_CMD=microdnf
INSTALL_CMD="${PKG_MGR_CMD} ${INSTALL_CMD_ADDL_REPOS} -y install --refresh --best --nodocs --noplugins --setopt=install_weak_deps=0"
elif type dnf > /dev/null 2>&1; then
PKG_MGR_CMD=dnf
INSTALL_CMD="${PKG_MGR_CMD} ${INSTALL_CMD_ADDL_REPOS} -y install --refresh --best --nodocs --noplugins --setopt=install_weak_deps=0"
else
PKG_MGR_CMD=yum
INSTALL_CMD="${PKG_MGR_CMD} ${INSTALL_CMD_ADDL_REPOS} -y install --noplugins --setopt=install_weak_deps=0"
fi
# Clean up
clean_up() {
case ${ADJUSTED_ID} in
debian)
rm -rf /var/lib/apt/lists/*
;;
rhel)
rm -rf /var/cache/dnf/* /var/cache/yum/*
rm -rf /tmp/yum.log
rm -rf ${GPG_INSTALL_PATH}
;;
esac
}
clean_up
updaterc() {
local _bashrc
local _zshrc
if [ "${UPDATE_RC}" = "true" ]; then
echo "Updating /etc/bash.bashrc and /etc/zsh/zshrc..."
if [[ "$(cat /etc/bash.bashrc)" != *"$1"* ]]; then
echo -e "$1" >> /etc/bash.bashrc
fi
if [ -f "/etc/zsh/zshrc" ] && [[ "$(cat /etc/zsh/zshrc)" != *"$1"* ]]; then
echo -e "$1" >> /etc/zsh/zshrc
case $ADJUSTED_ID in
debian) echo "Updating /etc/bash.bashrc and /etc/zsh/zshrc..."
_bashrc=/etc/bash.bashrc
_zshrc=/etc/zsh/zshrc
;;
rhel) echo "Updating /etc/bashrc and /etc/zshrc..."
_bashrc=/etc/bashrc
_zshrc=/etc/zshrc
;;
esac
if [[ "$(cat ${_bashrc})" != *"$1"* ]]; then
echo -e "$1" >> ${_bashrc}
fi
if [ -f "${_zshrc}" ] && [[ "$(cat ${_zshrc})" != *"$1"* ]]; then
echo -e "$1" >> ${_zshrc}
fi
fi
}
......@@ -83,6 +133,7 @@ updaterc() {
receive_gpg_keys() {
local keys=${!1}
local keyring_args=""
local gpg_cmd="gpg"
if [ ! -z "$2" ]; then
mkdir -p "$(dirname \"$2\")"
keyring_args="--no-default-keyring --keyring $2"
......@@ -116,6 +167,51 @@ receive_gpg_keys() {
exit 1
fi
}
# RHEL7/CentOS7 has an older gpg that does not have dirmngr
# Iterate through keyservers until we have all the keys downloaded
receive_gpg_keys_centos7() {
local keys=${!1}
local keyring_args=""
local gpg_cmd="gpg"
if [ ! -z "$2" ]; then
mkdir -p "$(dirname \"$2\")"
keyring_args="--no-default-keyring --keyring $2"
fi
if [ ! -z "${KEYSERVER_PROXY}" ]; then
keyring_args="${keyring_args} --keyserver-options http-proxy=${KEYSERVER_PROXY}"
fi
# Use a temporary location for gpg keys to avoid polluting image
export GNUPGHOME="/tmp/tmp-gnupg"
mkdir -p ${GNUPGHOME}
chmod 700 ${GNUPGHOME}
# GPG key download sometimes fails for some reason and retrying fixes it.
local retry_count=0
local gpg_ok="false"
num_keys=$(echo ${keys} | wc -w)
set +e
echo "(*) Downloading GPG keys..."
until [ "${gpg_ok}" = "true" ] || [ "${retry_count}" -eq "5" ]; do
for keyserver in $(echo "${GPG_KEY_SERVERS}" | sed 's/keyserver //'); do
( echo "${keys}" | xargs -n 1 gpg -q ${keyring_args} --recv-keys --keyserver=${keyserver} ) 2>&1
downloaded_keys=$(gpg --list-keys | grep ^pub | wc -l)
if [[ ${num_keys} = ${downloaded_keys} ]]; then
gpg_ok="true"
break
fi
done
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() {
......@@ -189,20 +285,52 @@ oryx_install() {
fi
}
apt_get_update()
{
pkg_mgr_update() {
case $ADJUSTED_ID in
debian)
if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then
echo "Running apt-get update..."
apt-get update -y
${PKG_MGR_CMD} update -y
fi
;;
rhel)
if [ ${PKG_MGR_CMD} = "microdnf" ]; then
if [ "$(ls /var/cache/yum/* 2>/dev/null | wc -l)" = 0 ]; then
echo "Running ${PKG_MGR_CMD} makecache ..."
${PKG_MGR_CMD} makecache
fi
else
if [ "$(ls /var/cache/${PKG_MGR_CMD}/* 2>/dev/null | wc -l)" = 0 ]; then
echo "Running ${PKG_MGR_CMD} check-update ..."
set +e
${PKG_MGR_CMD} check-update
rc=$?
if [ $rc != 0 ] && [ $rc != 100 ]; then
exit 1
fi
set -e
fi
fi
;;
esac
}
# Checks if packages are installed and installs them if not
check_packages() {
case ${ADJUSTED_ID} in
debian)
if ! dpkg -s "$@" > /dev/null 2>&1; then
apt_get_update
apt-get -y install --no-install-recommends "$@"
pkg_mgr_update
${INSTALL_CMD} "$@"
fi
;;
rhel)
if ! rpm -q "$@" > /dev/null 2>&1; then
pkg_mgr_update
${INSTALL_CMD} "$@"
fi
;;
esac
}
add_symlink() {
......@@ -218,13 +346,30 @@ add_symlink() {
fi
}
install_openssl3() {
local _prefix=$1
mkdir /tmp/openssl3
(
cd /tmp/openssl3
openssl3_version="3.0"
# Find version using soft match
find_version_from_git_tags openssl3_version "https://github.com/openssl/openssl" "openssl-"
local tgz_filename="openssl-${openssl3_version}.tar.gz"
local tgz_url="https://github.com/openssl/openssl/releases/download/openssl-${openssl3_version}/${tgz_filename}"
echo "Downloading ${tgz_filename}..."
curl -sSL -o "/tmp/openssl3/${tgz_filename}" "${tgz_url}"
tar xzf ${tgz_filename}
cd openssl-${openssl3_version}
./config --prefix=${_prefix} --openssldir=${_prefix} --libdir=lib
make -j $(nproc)
make install_dev
)
rm -rf /tmp/openssl3
}
install_from_source() {
VERSION=$1
echo "(*) Building Python ${VERSION} from source..."
# Install prereqs if missing
check_packages curl ca-certificates gnupg2 tar make gcc libssl-dev zlib1g-dev libncurses5-dev \
libbz2-dev libreadline-dev libxml2-dev xz-utils libgdbm-dev tk-dev dirmngr \
libxmlsec1-dev libsqlite3-dev libffi-dev liblzma-dev uuid-dev
if ! type git > /dev/null 2>&1; then
check_packages git
fi
......@@ -239,6 +384,17 @@ install_from_source() {
exit 1
fi
# Some platforms/os versions need modern versions of openssl installed
# via common package repositories, for now rhel-7 family, use case statement to
# make it easy to expand
case ${VERSION_CODENAME} in
centos7|rhel7)
check_packages perl-IPC-Cmd
install_openssl3 ${INSTALL_PATH}
ADDL_CONFIG_ARGS="--with-openssl=${INSTALL_PATH} --with-openssl-rpath=${INSTALL_PATH}/lib"
;;
esac
# Download tgz of source
mkdir -p /tmp/python-src ${INSTALL_PATH}
cd /tmp/python-src
......@@ -248,13 +404,21 @@ install_from_source() {
curl -sSL -o "/tmp/python-src/${tgz_filename}" "${tgz_url}"
# Verify signature
if [[ ${VERSION_CODENAME} = "centos7" ]] || [[ ${VERSION_CODENAME} = "rhel7" ]]; then
receive_gpg_keys_centos7 PYTHON_SOURCE_GPG_KEYS
else
receive_gpg_keys PYTHON_SOURCE_GPG_KEYS
fi
echo "Downloading ${tgz_filename}.asc..."
curl -sSL -o "/tmp/python-src/${tgz_filename}.asc" "${tgz_url}.asc"
gpg --verify "${tgz_filename}.asc"
# Update min protocol for testing only - https://bugs.python.org/issue41561
if [ -f /etc/pki/tls/openssl.cnf ]; then
cp /etc/pki/tls/openssl.cnf /tmp/python-src/
else
cp /etc/ssl/openssl.cnf /tmp/python-src/
fi
sed -i -E 's/MinProtocol[=\ ]+.*/MinProtocol = TLSv1.0/g' /tmp/python-src/openssl.cnf
export OPENSSL_CONF=/tmp/python-src/openssl.cnf
......@@ -262,11 +426,21 @@ install_from_source() {
tar -xzf "/tmp/python-src/${tgz_filename}" -C "/tmp/python-src" --strip-components=1
local config_args=""
if [ "${OPTIMIZE_BUILD_FROM_SOURCE}" = "true" ]; then
config_args="--enable-optimizations"
config_args="${config_args} --enable-optimizations"
fi
if [ "${ENABLESHARED}" = "true" ]; then
config_args=" ${config_args} --enable-shared"
# need double-$: LDFLAGS ends up in Makefile $$ becomes $ when evaluated.
# backslash needed for shell that Make calls escape the $.
export LDFLAGS="${LDFLAGS} -Wl,-rpath="'\$$ORIGIN'"/../lib"
fi
if [ -n "${ADDL_CONFIG_ARGS}" ]; then
config_args="${config_args} ${ADDL_CONFIG_ARGS}"
fi
./configure --prefix="${INSTALL_PATH}" --with-ensurepip=install ${config_args}
make -j 8
make install
cd /tmp
rm -rf /tmp/python-src ${GNUPGHOME} /tmp/vscdc-settings.env
......@@ -336,7 +510,15 @@ install_python() {
version=$1
# If the os-provided versions are "good enough", detect that and bail out.
if [ ${version} = "os-provided" ] || [ ${version} = "system" ]; then
if [ ${ADJUSTED_ID} = "debian" ]; then
check_packages python3 python3-doc python3-pip python3-venv python3-dev python3-tk
else
if [ ${ID} != "mariner" ]; then
check_packages python3 python3-pip python3-devel python3-tkinter
else
check_packages python3 python3-pip python3-devel
fi
fi
INSTALL_PATH="/usr"
local current_bin_path="${CURRENT_PATH}/bin"
......@@ -355,7 +537,7 @@ install_python() {
fi
should_install_from_source=false
elif [ "$(dpkg --print-architecture)" = "amd64" ] && [ "${USE_ORYX_IF_AVAILABLE}" = "true" ] && type oryx > /dev/null 2>&1; then
elif [ ${ADJUSTED_ID} = "debian" ] && [ "$(dpkg --print-architecture)" = "amd64" ] && [ "${USE_ORYX_IF_AVAILABLE}" = "true" ] && type oryx > /dev/null 2>&1; then
install_using_oryx $version || should_install_from_source=true
else
should_install_from_source=true
......@@ -365,14 +547,120 @@ install_python() {
fi
}
python_is_externally_managed() {
local _python_cmd=$1
local python_stdlib_dir=$(
${_python_cmd} -c '
import sys
import sysconfig
sys.prefix == sys.base_prefix and print(sysconfig.get_path("stdlib", sysconfig.get_default_scheme()))'
)
if [ -f ${python_stdlib_dir}/EXTERNALLY-MANAGED ]; then
return 0
else
return 1
fi
}
# Ensure that login shells get the correct path if the user updated the PATH using ENV.
rm -f /etc/profile.d/00-restore-env.sh
echo "export PATH=${PATH//$(sh -lc 'echo $PATH')/\$PATH}" > /etc/profile.d/00-restore-env.sh
chmod +x /etc/profile.d/00-restore-env.sh
# Some distributions do not install awk by default (e.g. Mariner)
if ! type awk >/dev/null 2>&1; then
check_packages awk
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
# General requirements
check_packages curl ca-certificates gnupg2 tar make gcc libssl-dev zlib1g-dev libncurses5-dev \
libbz2-dev libreadline-dev libxml2-dev xz-utils libgdbm-dev tk-dev dirmngr \
libxmlsec1-dev libsqlite3-dev libffi-dev liblzma-dev uuid-dev
REQUIRED_PKGS=""
case ${ADJUSTED_ID} in
debian)
REQUIRED_PKGS="${REQUIRED_PKGS} \
ca-certificates \
curl \
dirmngr \
gcc \
gnupg2 \
libbz2-dev \
libffi-dev \
libgdbm-dev \
liblzma-dev \
libncurses5-dev \
libreadline-dev \
libsqlite3-dev \
libssl-dev \
libxml2-dev \
libxmlsec1-dev \
make \
tar \
tk-dev \
uuid-dev \
xz-utils \
zlib1g-dev"
;;
rhel)
REQUIRED_PKGS="${REQUIRED_PKGS} \
bzip2-devel \
ca-certificates \
findutils \
gcc \
gnupg2 \
libffi-devel \
libxml2-devel \
make \
ncurses-devel \
openssl-devel \
shadow-utils \
sqlite-devel \
tar \
which \
xz-devel \
xz \
zlib-devel"
if ! type curl >/dev/null 2>&1; then
REQUIRED_PKGS="${REQUIRED_PKGS} \
curl"
fi
# Mariner does not have tk-devel package available, RedHat ubi8 and ubi9 do not have tk-devel
if [ ${ID} != "mariner" ] && [ ${ID} != "rhel" ]; then
REQUIRED_PKGS="${REQUIRED_PKGS} \
tk-devel"
fi
# Redhat ubi8 and ubi9 do not have some packages by default, only add them
# if we're not on RedHat ...
if [ ${ID} != "rhel" ]; then
REQUIRED_PKGS="${REQUIRED_PKGS} \
gdbm-devel \
readline-devel \
uuid-devel \
xmlsec1-devel"
fi
;;
esac
check_packages ${REQUIRED_PKGS}
# Install Python from source if needed
if [ "${PYTHON_VERSION}" != "none" ]; then
......@@ -410,12 +698,15 @@ if [ "${PYTHON_VERSION}" != "none" ]; then
find "${PYTHON_INSTALL_PATH}" -type d -print0 | xargs -0 -n 1 chmod g+s
PYTHON_SRC="${INSTALL_PATH}/bin/python3"
if ! type pip >/dev/null 2>&1 && type pip3 >/dev/null 2>&1; then
ln -s /usr/bin/pip3 /usr/bin/pip
fi
else
PYTHON_SRC=$(which python)
fi
# Install Python tools if needed
if [[ "${INSTALL_PYTHON_TOOLS}" = "true" ]] && [[ $(python --version) != "" ]]; then
if [[ "${INSTALL_PYTHON_TOOLS}" = "true" ]] && [[ -n "${PYTHON_SRC}" ]]; then
echo 'Installing Python tools...'
export PIPX_BIN_DIR="${PIPX_HOME}/bin"
PATH="${PATH}:${PIPX_BIN_DIR}"
......@@ -432,21 +723,24 @@ if [[ "${INSTALL_PYTHON_TOOLS}" = "true" ]] && [[ $(python --version) != "" ]];
find "${PIPX_HOME}" -type d -print0 | xargs -0 -n 1 chmod g+s
# Update pip if not using os provided python
if [[ $(python --version) != "" ]] || [[ ${PYTHON_VERSION} != "os-provided" ]] && [[ ${PYTHON_VERSION} != "system" ]] && [[ ${PYTHON_VERSION} != "none" ]]; then
if [[ -n "${PYTHON_SRC}" ]] && [[ ${PYTHON_VERSION} != "os-provided" ]] && [[ ${PYTHON_VERSION} != "system" ]] && [[ ${PYTHON_VERSION} != "none" ]]; then
echo "Updating pip..."
python -m pip install --no-cache-dir --upgrade pip
${PYTHON_SRC} -m pip install --no-cache-dir --upgrade pip
fi
# Install tools
echo "Installing Python tools..."
export PYTHONUSERBASE=/tmp/pip-tmp
export PIP_CACHE_DIR=/tmp/pip-tmp/cache
PIPX_DIR=""
if ! type pipx > /dev/null 2>&1; then
if python_is_externally_managed ${PYTHON_SRC}; then
check_packages pipx
else
pip3 install --disable-pip-version-check --no-cache-dir --user pipx 2>&1
/tmp/pip-tmp/bin/pipx install --pip-args=--no-cache-dir pipx
PIPX_DIR="/tmp/pip-tmp/bin/"
fi
fi
for util in "${DEFAULT_UTILS[@]}"; do
if ! type ${util} > /dev/null 2>&1; then
"${PIPX_DIR}pipx" install --system-site-packages --pip-args '--no-cache-dir --force-reinstall' ${util}
......@@ -458,7 +752,7 @@ if [[ "${INSTALL_PYTHON_TOOLS}" = "true" ]] && [[ $(python --version) != "" ]];
# Temporary: Removes “setup tools” metadata directory due to https://github.com/advisories/GHSA-r9hx-vwmv-q579
VULNERABLE_VERSIONS=("3.10" "3.11")
RUN_TIME_PY_VER_DETECT=$(python --version 2>&1)
RUN_TIME_PY_VER_DETECT=$(${PYTHON_SRC} --version 2>&1)
PY_MAJOR_MINOR_VER=${RUN_TIME_PY_VER_DETECT:7:4};
if [[ ${VULNERABLE_VERSIONS[*]} =~ $PY_MAJOR_MINOR_VER ]]; then
rm -rf ${PIPX_HOME}/shared/lib/"python${PY_MAJOR_MINOR_VER}"/site-packages/setuptools-65.5.0.dist-info
......@@ -502,6 +796,6 @@ if [ "${INSTALL_JUPYTERLAB}" = "true" ]; then
fi
# Clean up
rm -rf /var/lib/apt/lists/*
clean_up
echo "Done!"
#!/bin/bash
set -e
# Optional: Import test library
source dev-container-features-test-lib
# Definition specific tests
check "version" python --version
check "pip is installed" pip --version
check "pip is installed" pip3 --version
# Check that tools can execute
check "autopep8" autopep8 --version
check "black" black --version
check "yapf" yapf --version
check "bandit" bandit --version
check "flake8" flake8 --version
check "mypy" mypy --version
check "pycodestyle" pycodestyle --version
check "pydocstyle" pydocstyle --version
check "pylint" pylint --version
check "pytest" pytest --version
# Check paths in settings
check "current symlink is correct" bash -c "which python | grep /usr/local/python/current/bin/python"
check "current symlink works" /usr/local/python/current/bin/python --version
check "which autopep8" bash -c "which autopep8 | grep /usr/local/py-utils/bin/autopep8"
check "which black" bash -c "which black | grep /usr/local/py-utils/bin/black"
check "which yapf" bash -c "which yapf | grep /usr/local/py-utils/bin/yapf"
check "which bandit" bash -c "which bandit | grep /usr/local/py-utils/bin/bandit"
check "which flake8" bash -c "which flake8 | grep /usr/local/py-utils/bin/flake8"
check "which mypy" bash -c "which mypy | grep /usr/local/py-utils/bin/mypy"
check "which pycodestyle" bash -c "which pycodestyle | grep /usr/local/py-utils/bin/pycodestyle"
check "which pydocstyle" bash -c "which pydocstyle | grep /usr/local/py-utils/bin/pydocstyle"
check "which pylint" bash -c "which pylint | grep /usr/local/py-utils/bin/pylint"
check "which pytest" bash -c "which pytest | grep /usr/local/py-utils/bin/pytest"
# Report result
reportResults
#!/bin/bash
set -e
# Optional: Import test library
source dev-container-features-test-lib
# Definition specific tests
check "version" python --version
check "pip is installed" pip --version
check "pip is installed" pip3 --version
# Check that tools can execute
check "autopep8" autopep8 --version
check "black" black --version
check "yapf" yapf --version
check "bandit" bandit --version
check "flake8" flake8 --version
check "mypy" mypy --version
check "pycodestyle" pycodestyle --version
check "pydocstyle" pydocstyle --version
check "pylint" pylint --version
check "pytest" pytest --version
# Check paths in settings
check "current symlink is correct" bash -c "which python | grep /usr/local/python/current/bin/python"
check "current symlink works" /usr/local/python/current/bin/python --version
check "which autopep8" bash -c "which autopep8 | grep /usr/local/py-utils/bin/autopep8"
check "which black" bash -c "which black | grep /usr/local/py-utils/bin/black"
check "which yapf" bash -c "which yapf | grep /usr/local/py-utils/bin/yapf"
check "which bandit" bash -c "which bandit | grep /usr/local/py-utils/bin/bandit"
check "which flake8" bash -c "which flake8 | grep /usr/local/py-utils/bin/flake8"
check "which mypy" bash -c "which mypy | grep /usr/local/py-utils/bin/mypy"
check "which pycodestyle" bash -c "which pycodestyle | grep /usr/local/py-utils/bin/pycodestyle"
check "which pydocstyle" bash -c "which pydocstyle | grep /usr/local/py-utils/bin/pydocstyle"
check "which pylint" bash -c "which pylint | grep /usr/local/py-utils/bin/pylint"
check "which pytest" bash -c "which pytest | grep /usr/local/py-utils/bin/pytest"
# Report result
reportResults
#!/bin/bash
set -e
# Optional: Import test library
source dev-container-features-test-lib
# Definition specific tests
check "version" python --version
check "pip is installed" pip --version
check "pip is installed" pip3 --version
# Check that tools can execute
check "autopep8" autopep8 --version
check "black" black --version
check "yapf" yapf --version
check "bandit" bandit --version
check "flake8" flake8 --version
check "mypy" mypy --version
check "pycodestyle" pycodestyle --version
check "pydocstyle" pydocstyle --version
check "pylint" pylint --version
check "pytest" pytest --version
# Check paths in settings
check "current symlink is correct" bash -c "which python | grep /usr/local/python/current/bin/python"
check "current symlink works" /usr/local/python/current/bin/python --version
check "which autopep8" bash -c "which autopep8 | grep /usr/local/py-utils/bin/autopep8"
check "which black" bash -c "which black | grep /usr/local/py-utils/bin/black"
check "which yapf" bash -c "which yapf | grep /usr/local/py-utils/bin/yapf"
check "which bandit" bash -c "which bandit | grep /usr/local/py-utils/bin/bandit"
check "which flake8" bash -c "which flake8 | grep /usr/local/py-utils/bin/flake8"
check "which mypy" bash -c "which mypy | grep /usr/local/py-utils/bin/mypy"
check "which pycodestyle" bash -c "which pycodestyle | grep /usr/local/py-utils/bin/pycodestyle"
check "which pydocstyle" bash -c "which pydocstyle | grep /usr/local/py-utils/bin/pydocstyle"
check "which pylint" bash -c "which pylint | grep /usr/local/py-utils/bin/pylint"
check "which pytest" bash -c "which pytest | grep /usr/local/py-utils/bin/pytest"
# Report result
reportResults
#!/bin/bash
set -e
# Optional: Import test library
source dev-container-features-test-lib
# Definition specific tests
check "version" python --version
check "pip is installed" pip --version
check "pip is installed" pip3 --version
# Check that tools can execute
check "autopep8" autopep8 --version
check "black" black --version
check "yapf" yapf --version
check "bandit" bandit --version
check "flake8" flake8 --version
check "mypy" mypy --version
check "pycodestyle" pycodestyle --version
check "pydocstyle" pydocstyle --version
check "pylint" pylint --version
check "pytest" pytest --version
# Check paths in settings
check "current symlink is correct" bash -c "which python | grep /usr/local/python/current/bin/python"
check "current symlink works" /usr/local/python/current/bin/python --version
check "which autopep8" bash -c "which autopep8 | grep /usr/local/py-utils/bin/autopep8"
check "which black" bash -c "which black | grep /usr/local/py-utils/bin/black"
check "which yapf" bash -c "which yapf | grep /usr/local/py-utils/bin/yapf"
check "which bandit" bash -c "which bandit | grep /usr/local/py-utils/bin/bandit"
check "which flake8" bash -c "which flake8 | grep /usr/local/py-utils/bin/flake8"
check "which mypy" bash -c "which mypy | grep /usr/local/py-utils/bin/mypy"
check "which pycodestyle" bash -c "which pycodestyle | grep /usr/local/py-utils/bin/pycodestyle"
check "which pydocstyle" bash -c "which pydocstyle | grep /usr/local/py-utils/bin/pydocstyle"
check "which pylint" bash -c "which pylint | grep /usr/local/py-utils/bin/pylint"
check "which pytest" bash -c "which pytest | grep /usr/local/py-utils/bin/pytest"
# Report result
reportResults
#!/bin/bash
set -e
# Optional: Import test library
source dev-container-features-test-lib
# Definition specific tests
check "version" python --version
check "pip is installed" pip --version
check "pip is installed" pip3 --version
# Check that tools can execute
check "autopep8" autopep8 --version
check "black" black --version
check "yapf" yapf --version
check "bandit" bandit --version
check "flake8" flake8 --version
check "mypy" mypy --version
check "pycodestyle" pycodestyle --version
check "pydocstyle" pydocstyle --version
check "pylint" pylint --version
check "pytest" pytest --version
# Check paths in settings
check "current symlink is correct" bash -c "which python | grep /usr/local/python/current/bin/python"
check "current symlink works" /usr/local/python/current/bin/python --version
check "which autopep8" bash -c "which autopep8 | grep /usr/local/py-utils/bin/autopep8"
check "which black" bash -c "which black | grep /usr/local/py-utils/bin/black"
check "which yapf" bash -c "which yapf | grep /usr/local/py-utils/bin/yapf"
check "which bandit" bash -c "which bandit | grep /usr/local/py-utils/bin/bandit"
check "which flake8" bash -c "which flake8 | grep /usr/local/py-utils/bin/flake8"
check "which mypy" bash -c "which mypy | grep /usr/local/py-utils/bin/mypy"
check "which pycodestyle" bash -c "which pycodestyle | grep /usr/local/py-utils/bin/pycodestyle"
check "which pydocstyle" bash -c "which pydocstyle | grep /usr/local/py-utils/bin/pydocstyle"
check "which pylint" bash -c "which pylint | grep /usr/local/py-utils/bin/pylint"
check "which pytest" bash -c "which pytest | grep /usr/local/py-utils/bin/pytest"
# Report result
reportResults
#!/bin/bash
set -e
# Optional: Import test library
source dev-container-features-test-lib
# Definition specific tests
check "version" python --version
check "pip is installed" pip --version
check "pip is installed" pip3 --version
# Check that tools can execute
check "autopep8" autopep8 --version
check "black" black --version
check "yapf" yapf --version
check "bandit" bandit --version
check "flake8" flake8 --version
check "mypy" mypy --version
check "pycodestyle" pycodestyle --version
check "pydocstyle" pydocstyle --version
check "pylint" pylint --version
check "pytest" pytest --version
# Check paths in settings
check "current symlink is correct" bash -c "which python | grep /usr/local/python/current/bin/python"
check "current symlink works" /usr/local/python/current/bin/python --version
check "which autopep8" bash -c "which autopep8 | grep /usr/local/py-utils/bin/autopep8"
check "which black" bash -c "which black | grep /usr/local/py-utils/bin/black"
check "which yapf" bash -c "which yapf | grep /usr/local/py-utils/bin/yapf"
check "which bandit" bash -c "which bandit | grep /usr/local/py-utils/bin/bandit"
check "which flake8" bash -c "which flake8 | grep /usr/local/py-utils/bin/flake8"
check "which mypy" bash -c "which mypy | grep /usr/local/py-utils/bin/mypy"
check "which pycodestyle" bash -c "which pycodestyle | grep /usr/local/py-utils/bin/pycodestyle"
check "which pydocstyle" bash -c "which pydocstyle | grep /usr/local/py-utils/bin/pydocstyle"
check "which pylint" bash -c "which pylint | grep /usr/local/py-utils/bin/pylint"
check "which pytest" bash -c "which pytest | grep /usr/local/py-utils/bin/pytest"
# Report result
reportResults
#!/bin/bash
set -e
# Optional: Import test library
source dev-container-features-test-lib
# Always run these checks as the non-root user
user="$(whoami)"
check "user" grep vscode <<< "$user"
# Check for an installation of JupyterLab
check "version" jupyter lab --version
# Check location of JupyterLab installation
packages="$(python3 -m pip list)"
check "location" grep jupyter <<< "$packages"
# Check for git extension
check "jupyterlab_git" grep jupyterlab_git <<< "$packages"
# Check for correct JupyterLab configuration
check "config" grep ".*.allow_origin = '*'" /home/vscode/.jupyter/jupyter_server_config.py
# Report result
reportResults
#!/bin/bash
set -e
# Optional: Import test library
source dev-container-features-test-lib
check "python version 3.11 installed as default" bash -c "python --version | grep 3.11"
check "python3 version 3.11 installed as default" bash -c "python3 --version | grep 3.11"
check "python version 3.10.5 installed" bash -c "ls -l /usr/local/python | grep 3.10.5"
check "python version 3.8 installed" bash -c "ls -l /usr/local/python | grep 3.8"
check "python version 3.9.13 installed" bash -c "ls -l /usr/local/python | grep 3.9.13"
# Check that tools can execute - make sure something didn't get messed up in this scenario
check "autopep8" autopep8 --version
check "black" black --version
check "yapf" yapf --version
check "bandit" bandit --version
check "flake8" flake8 --version
check "mypy" mypy --version
check "pycodestyle" pycodestyle --version
check "pydocstyle" pydocstyle --version
check "pylint" pylint --version
check "pytest" pytest --version
# Check paths in settings
check "current symlink is correct" bash -c "which python | grep /usr/local/python/current/bin/python"
check "current symlink works" /usr/local/python/current/bin/python --version
check "which autopep8" bash -c "which autopep8 | grep /usr/local/py-utils/bin/autopep8"
check "which black" bash -c "which black | grep /usr/local/py-utils/bin/black"
check "which yapf" bash -c "which yapf | grep /usr/local/py-utils/bin/yapf"
check "which bandit" bash -c "which bandit | grep /usr/local/py-utils/bin/bandit"
check "which flake8" bash -c "which flake8 | grep /usr/local/py-utils/bin/flake8"
check "which mypy" bash -c "which mypy | grep /usr/local/py-utils/bin/mypy"
check "which pycodestyle" bash -c "which pycodestyle | grep /usr/local/py-utils/bin/pycodestyle"
check "which pydocstyle" bash -c "which pydocstyle | grep /usr/local/py-utils/bin/pydocstyle"
check "which pylint" bash -c "which pylint | grep /usr/local/py-utils/bin/pylint"
check "which pytest" bash -c "which pytest | grep /usr/local/py-utils/bin/pytest"
# Report result
reportResults
#!/bin/bash
set -e
# Optional: Import test library
source dev-container-features-test-lib
# Definition specific tests
check "version" python --version
check "pip is installed" pip --version
check "pip is installed" pip3 --version
# Check that tools can execute
check "bandit" bandit --version
check "mypy" mypy --version
check "pipenv" pipenv --version
check "pytest" pytest --version
check "ruff" ruff --version
check "virtualenv" virtualenv --version
# Check paths in settings
check "current symlink is correct" bash -c "which python | grep /usr/local/python/current/bin/python"
check "current symlink works" /usr/local/python/current/bin/python --version
check "which bandit" bash -c "which bandit | grep /usr/local/py-utils/bin/bandit"
check "which mypy" bash -c "which mypy | grep /usr/local/py-utils/bin/mypy"
check "which pipenv" bash -c "which pipenv | grep /usr/local/py-utils/bin/pipenv"
check "which pytest" bash -c "which pytest | grep /usr/local/py-utils/bin/pytest"
check "which ruff" bash -c "which ruff | grep /usr/local/py-utils/bin/ruff"
check "which virtualenv" bash -c "which virtualenv | grep /usr/local/py-utils/bin/virtualenv"
# Report result
reportResults
#!/bin/bash
set -e
# Optional: Import test library
source dev-container-features-test-lib
# Definition specific tests
check "version" python --version
check "pip is installed" pip --version
check "pip is installed" pip3 --version
# Check that tools can execute
check "bandit" bandit --version
check "mypy" mypy --version
check "pipenv" pipenv --version
check "pytest" pytest --version
check "ruff" ruff --version
check "virtualenv" virtualenv --version
# Check paths in settings
check "current symlink is correct" bash -c "which python | grep /usr/local/python/current/bin/python"
check "current symlink works" /usr/local/python/current/bin/python --version
check "which bandit" bash -c "which bandit | grep /usr/local/py-utils/bin/bandit"
check "which mypy" bash -c "which mypy | grep /usr/local/py-utils/bin/mypy"
check "which pipenv" bash -c "which pipenv | grep /usr/local/py-utils/bin/pipenv"
check "which pytest" bash -c "which pytest | grep /usr/local/py-utils/bin/pytest"
check "which ruff" bash -c "which ruff | grep /usr/local/py-utils/bin/ruff"
check "which virtualenv" bash -c "which virtualenv | grep /usr/local/py-utils/bin/virtualenv"
# Report result
reportResults
#!/bin/bash
set -e
# Optional: Import test library
source dev-container-features-test-lib
# Always run these checks as the non-root user
user="$(whoami)"
check "user" grep vscode <<< "$user"
# Check for an installation of JupyterLab
check "version" jupyter lab --version
# Check location of JupyterLab installation
packages="$(python3 -m pip list)"
check "location" grep jupyter <<< "$packages"
# Check for git extension
check "jupyterlab_git" grep jupyterlab_git <<< "$packages"
# Check for correct JupyterLab configuration
check "config" grep ".*.allow_origin = '*'" /home/vscode/.jupyter/jupyter_server_config.py
# Report result
reportResults
#!/bin/bash
set -e
# Optional: Import test library
source dev-container-features-test-lib
check "python3 is installed" python3 --version
check "python is installed" python --version
check "pip is installed" pip --version
check "pip is installed" pip3 --version
# Check that tools can execute
check "autopep8" autopep8 --version
check "black" black --version
check "yapf" yapf --version
check "bandit" bandit --version
check "flake8" flake8 --version
check "mypy" mypy --version
check "pycodestyle" pycodestyle --version
check "pydocstyle" pydocstyle --version
check "pylint" pylint --version
check "pytest" pytest --version
# Check paths in settings
check "current symlink is correct" bash -c "which python | grep /usr/local/python/current/bin/python"
check "current symlink works" /usr/local/python/current/bin/python --version
check "which autopep8" bash -c "which autopep8 | grep /usr/local/py-utils/bin/autopep8"
check "which black" bash -c "which black | grep /usr/local/py-utils/bin/black"
check "which yapf" bash -c "which yapf | grep /usr/local/py-utils/bin/yapf"
check "which bandit" bash -c "which bandit | grep /usr/local/py-utils/bin/bandit"
check "which flake8" bash -c "which flake8 | grep /usr/local/py-utils/bin/flake8"
check "which mypy" bash -c "which mypy | grep /usr/local/py-utils/bin/mypy"
check "which pycodestyle" bash -c "which pycodestyle | grep /usr/local/py-utils/bin/pycodestyle"
check "which pydocstyle" bash -c "which pydocstyle | grep /usr/local/py-utils/bin/pydocstyle"
check "which pylint" bash -c "which pylint | grep /usr/local/py-utils/bin/pylint"
check "which pytest" bash -c "which pytest | grep /usr/local/py-utils/bin/pytest"
# Report result
reportResults
#!/bin/bash
set -e
# Optional: Import test library
source dev-container-features-test-lib
check "python3 is installed" python3 --version
check "python is installed" python --version
check "pip is installed" pip --version
check "pip is installed" pip3 --version
# Check that tools can execute
check "autopep8" autopep8 --version
check "black" black --version
check "yapf" yapf --version
check "bandit" bandit --version
check "flake8" flake8 --version
check "mypy" mypy --version
check "pycodestyle" pycodestyle --version
check "pydocstyle" pydocstyle --version
check "pylint" pylint --version
check "pytest" pytest --version
# Check paths in settings
check "current symlink is correct" bash -c "which python | grep /usr/local/python/current/bin/python"
check "current symlink works" /usr/local/python/current/bin/python --version
check "which autopep8" bash -c "which autopep8 | grep /usr/local/py-utils/bin/autopep8"
check "which black" bash -c "which black | grep /usr/local/py-utils/bin/black"
check "which yapf" bash -c "which yapf | grep /usr/local/py-utils/bin/yapf"
check "which bandit" bash -c "which bandit | grep /usr/local/py-utils/bin/bandit"
check "which flake8" bash -c "which flake8 | grep /usr/local/py-utils/bin/flake8"
check "which mypy" bash -c "which mypy | grep /usr/local/py-utils/bin/mypy"
check "which pycodestyle" bash -c "which pycodestyle | grep /usr/local/py-utils/bin/pycodestyle"
check "which pydocstyle" bash -c "which pydocstyle | grep /usr/local/py-utils/bin/pydocstyle"
check "which pylint" bash -c "which pylint | grep /usr/local/py-utils/bin/pylint"
check "which pytest" bash -c "which pytest | grep /usr/local/py-utils/bin/pytest"
# Report result
reportResults
......@@ -78,10 +78,6 @@ checkVulnerableDir()
fi
}
bash -c "echo -e -n '\n'";
bash -c "echo -e 'Files/Folders related to setuptools :-'";
bash -c "find / -name \"*setuptools*\";"
# only for 3.10
checkVulnerableDir "/usr/local/py-utils/shared/lib/python3.10/site-packages/setuptools-65.5.0.dist-info" "3.10"
......
......@@ -79,10 +79,6 @@ checkVulnerableDir()
fi
}
bash -c "echo -e -n '\n'";
bash -c "echo -e 'Files/Folders related to setuptools :-'";
bash -c "find / -name \"*setuptools*\";"
# only for 3.11
checkVulnerableDir "/usr/local/py-utils/shared/lib/python3.11/site-packages/setuptools-65.5.0.dist-info" "3.11"
......
#!/bin/bash
set -e
# Optional: Import test library
source dev-container-features-test-lib
# Definition specific tests
check "version" python --version
check "pip is installed" pip --version
check "pip is installed" pip3 --version
# Check that tools can execute
check "autopep8" autopep8 --version
check "black" black --version
check "yapf" yapf --version
check "bandit" bandit --version
check "flake8" flake8 --version
check "mypy" mypy --version
check "pycodestyle" pycodestyle --version
check "pydocstyle" pydocstyle --version
check "pylint" pylint --version
check "pytest" pytest --version
# Check paths in settings
check "current symlink is correct" bash -c "which python | grep /usr/local/python/current/bin/python"
check "current symlink works" /usr/local/python/current/bin/python --version
check "which autopep8" bash -c "which autopep8 | grep /usr/local/py-utils/bin/autopep8"
check "which black" bash -c "which black | grep /usr/local/py-utils/bin/black"
check "which yapf" bash -c "which yapf | grep /usr/local/py-utils/bin/yapf"
check "which bandit" bash -c "which bandit | grep /usr/local/py-utils/bin/bandit"
check "which flake8" bash -c "which flake8 | grep /usr/local/py-utils/bin/flake8"
check "which mypy" bash -c "which mypy | grep /usr/local/py-utils/bin/mypy"
check "which pycodestyle" bash -c "which pycodestyle | grep /usr/local/py-utils/bin/pycodestyle"
check "which pydocstyle" bash -c "which pydocstyle | grep /usr/local/py-utils/bin/pydocstyle"
check "which pylint" bash -c "which pylint | grep /usr/local/py-utils/bin/pylint"
check "which pytest" bash -c "which pytest | grep /usr/local/py-utils/bin/pytest"
# Check compiled with "--enable-shared" -- python truth is opposite of the shells
# therefore we negate the check to get a '0' exit code when the python
# has been compiled with --enable-shared
check "python enable shared" /usr/local/python/current/bin/python -c 'import sys; import sysconfig; sys.exit(sysconfig.get_config_vars("Py_ENABLE_SHARED") != [1])'
# Report result
reportResults
#!/bin/bash
set -e
# Optional: Import test library
source dev-container-features-test-lib
# Definition specific tests
check "version" python --version
check "pip is installed" pip --version
check "pip is installed" pip3 --version
# Check that tools can execute
check "autopep8" autopep8 --version
check "black" black --version
check "yapf" yapf --version
check "bandit" bandit --version
check "flake8" flake8 --version
check "mypy" mypy --version
check "pycodestyle" pycodestyle --version
check "pydocstyle" pydocstyle --version
check "pylint" pylint --version
check "pytest" pytest --version
# Check paths in settings
check "current symlink is correct" bash -c "which python | grep /usr/local/python/current/bin/python"
check "current symlink works" /usr/local/python/current/bin/python --version
check "which autopep8" bash -c "which autopep8 | grep /usr/local/py-utils/bin/autopep8"
check "which black" bash -c "which black | grep /usr/local/py-utils/bin/black"
check "which yapf" bash -c "which yapf | grep /usr/local/py-utils/bin/yapf"
check "which bandit" bash -c "which bandit | grep /usr/local/py-utils/bin/bandit"
check "which flake8" bash -c "which flake8 | grep /usr/local/py-utils/bin/flake8"
check "which mypy" bash -c "which mypy | grep /usr/local/py-utils/bin/mypy"
check "which pycodestyle" bash -c "which pycodestyle | grep /usr/local/py-utils/bin/pycodestyle"
check "which pydocstyle" bash -c "which pydocstyle | grep /usr/local/py-utils/bin/pydocstyle"
check "which pylint" bash -c "which pylint | grep /usr/local/py-utils/bin/pylint"
check "which pytest" bash -c "which pytest | grep /usr/local/py-utils/bin/pytest"
# Check compiled with "--enable-shared" -- python truth is opposite of the shells
# therefore we negate the check to get a '0' exit code when the python
# has been compiled with --enable-shared
check "python enable shared" /usr/local/python/current/bin/python -c 'import sys; import sysconfig; sys.exit(sysconfig.get_config_vars("Py_ENABLE_SHARED") != [1])'
# Report result
reportResults
......@@ -26,6 +26,15 @@
}
}
},
"install_additional_python_rhel_family": {
"image": "almalinux:8",
"features": {
"python": {
"version": "3.11",
"additionalVersions": "3.8,3.9.13,3.10.5"
}
}
},
"install_jupyterlab": {
"image": "mcr.microsoft.com/devcontainers/base:focal",
"remoteUser": "vscode",
......@@ -37,6 +46,20 @@
}
}
},
"install_jupyterlab_rhel_family": {
"image": "almalinux:8",
"remoteUser": "vscode",
"features": {
"common-utils": {
"username": "vscode"
},
"python": {
"version": "latest",
"installJupyterlab": true,
"configureJupyterlabAllowOrigin": "*"
}
}
},
"install_additional_jupyterlab": {
"image": "mcr.microsoft.com/devcontainers/base:focal",
"remoteUser": "vscode",
......@@ -49,12 +72,39 @@
}
}
},
"install_os_provided_python": {
"install_additional_jupyterlab_rhel_family": {
"image": "almalinux:8",
"remoteUser": "vscode",
"features": {
"common-utils": {
"username": "vscode"
},
"python": {
"version": "latest",
"additionalVersions": "3.9",
"installJupyterlab": true,
"configureJupyterlabAllowOrigin": "*"
}
}
},
"install_os_provided_python_deb": {
"image": "mcr.microsoft.com/devcontainers/base:1-bullseye",
"features": {
"python": "os-provided"
}
},
"install_os_provided_python_rhel_family": {
"image": "almalinux:8",
"features": {
"python": "os-provided"
}
},
"install_os_provided_python_mariner": {
"image": "mcr.microsoft.com/cbl-mariner/base/core:2.0",
"features": {
"python": "os-provided"
}
},
"install_jupyterlab_from_python_image": {
"image": "mcr.microsoft.com/devcontainers/python:3.10-bullseye",
"remoteUser": "vscode",
......@@ -99,5 +149,89 @@
"version": "3.12"
}
}
},
"install_alternate_tools": {
"image": "mcr.microsoft.com/devcontainers/base:1-ubuntu-22.04",
"features": {
"python": {
"version": "3.12",
"toolsToInstall": "ruff,mypy,bandit,pipenv,virtualenv,pytest"
}
}
},
"install_alternate_tools_rhel_family": {
"image": "almalinux:8",
"features": {
"python": {
"version": "3.12",
"toolsToInstall": "ruff,mypy,bandit,pipenv,virtualenv,pytest"
}
}
},
"centos-7": {
"image": "centos:centos7",
"features": {
"python": {
"version": "3.11"
}
}
},
"alma-8": {
"image": "almalinux:8",
"features": {
"python": {
"version": "3.11"
}
}
},
"alma-8-minimal": {
"image": "almalinux:8-minimal",
"features": {
"python": {
"version": "3.11"
}
}
},
"alma-9": {
"image": "almalinux:9",
"features": {
"python": {
"version": "3.11"
}
}
},
"alma-9-minimal": {
"image": "almalinux:9-minimal",
"features": {
"python": {
"version": "3.11"
}
}
},
"fedora": {
"image": "fedora",
"features": {
"python": {
"version": "3.11"
}
}
},
"install_python_shared_lib_deb": {
"image": "ubuntu:focal",
"features": {
"python": {
"version": "3.11",
"enableShared": true
}
}
},
"install_python_shared_lib_rhel_family": {
"image": "almalinux:8",
"features": {
"python": {
"version": "3.11",
"enableShared": true
}
}
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment