diff --git a/.github/workflows/build-and-push.yml b/.github/workflows/build-and-push.yml index 65e62680..7cdbfca4 100644 --- a/.github/workflows/build-and-push.yml +++ b/.github/workflows/build-and-push.yml @@ -30,30 +30,6 @@ jobs: tag: "c9s" image_name: "python-39-minimal-c9s" - - dockerfile: "3.11-minimal/Dockerfile.rhel8" - docker_context: "3.11-minimal" - registry_namespace: "sclorg" - quayio_username: "QUAY_IMAGE_SCLORG_BUILDER_USERNAME" - quayio_token: "QUAY_IMAGE_SCLORG_BUILDER_TOKEN" - tag: "el8" - image_name: "python-311-minimal-el8" - - - dockerfile: "3.11-minimal/Dockerfile.c9s" - docker_context: "3.11-minimal" - registry_namespace: "sclorg" - quayio_username: "QUAY_IMAGE_SCLORG_BUILDER_USERNAME" - quayio_token: "QUAY_IMAGE_SCLORG_BUILDER_TOKEN" - tag: "c9s" - image_name: "python-311-minimal-c9s" - - - dockerfile: "3.11/Dockerfile.c9s" - docker_context: "3.11" - registry_namespace: "sclorg" - quayio_username: "QUAY_IMAGE_SCLORG_BUILDER_USERNAME" - quayio_token: "QUAY_IMAGE_SCLORG_BUILDER_TOKEN" - tag: "c9s" - image_name: "python-311-c9s" - - dockerfile: "3.12-minimal/Dockerfile.rhel8" docker_context: "3.12-minimal" registry_namespace: "sclorg" diff --git a/.github/workflows/container-tests.yml b/.github/workflows/container-tests.yml index 8570cb20..67904ab7 100644 --- a/.github/workflows/container-tests.yml +++ b/.github/workflows/container-tests.yml @@ -14,6 +14,6 @@ jobs: uses: "sclorg/ci-actions/.github/workflows/container-tests.yml@main" with: enabled-tests: '["container","container-pytest","openshift-pytest"]' - versions: '[ "3.9", "3.9-minimal", "3.11", "3.11-minimal", "3.12", "3.12-minimal", "3.13", "3.13-minimal", "3.14", "3.14-minimal" ]' - openshift-versions: '[ "3.8", "3.9", "3.11", "3.12", "3.12-minimal" ]' + versions: '[ "3.9", "3.9-minimal", "3.12", "3.12-minimal", "3.13", "3.13-minimal", "3.14", "3.14-minimal" ]' + openshift-versions: '[ "3.8", "3.9", "3.12", "3.12-minimal" ]' secrets: inherit diff --git a/3.11-minimal/Dockerfile.c9s b/3.11-minimal/Dockerfile.c9s deleted file mode 100644 index 874d7d22..00000000 --- a/3.11-minimal/Dockerfile.c9s +++ /dev/null @@ -1,104 +0,0 @@ -FROM quay.io/centos/centos:stream9-minimal - - -EXPOSE 8080 - -ENV PYTHON_VERSION=3.11 \ - PYTHONUNBUFFERED=1 \ - PYTHONIOENCODING=UTF-8 \ - LC_ALL=en_US.UTF-8 \ - LANG=en_US.UTF-8 \ - CNB_STACK_ID=com.redhat.stacks.ubi9-python-311 \ - CNB_USER_ID=1001 \ - CNB_GROUP_ID=0 \ - PIP_NO_CACHE_DIR=off \ - # The following variables are usually available from parent s2i images \ - STI_SCRIPTS_PATH=/usr/libexec/s2i \ - APP_ROOT=/opt/app-root \ - HOME=/opt/app-root/src \ - PLATFORM="el9" - -# /opt/app-root/bin - the main venv -# /opt/app-root/src/bin - app-specific binaries -# /opt/app-root/src/.local/bin - tools like pipenv -ENV PATH=$APP_ROOT/bin:$HOME/bin:$HOME/.local/bin:$PATH - -# Ensure the virtual environment is active in interactive shells -ENV BASH_ENV=${APP_ROOT}/bin/activate \ - ENV=${APP_ROOT}/bin/activate \ - PROMPT_COMMAND=". ${APP_ROOT}/bin/activate" - -ENV SUMMARY="Minimal platform for building and running Python $PYTHON_VERSION applications" \ - DESCRIPTION="Python $PYTHON_VERSION available as container is a base platform for \ -building and running various Python $PYTHON_VERSION applications and frameworks. \ -Python is an easy to learn, powerful programming language. It has efficient high-level \ -data structures and a simple but effective approach to object-oriented programming. \ -Python's elegant syntax and dynamic typing, together with its interpreted nature, \ -make it an ideal language for scripting and rapid application development in many areas \ -on most platforms." - -LABEL summary="$SUMMARY" \ - description="$DESCRIPTION" \ - io.k8s.description="$DESCRIPTION" \ - io.k8s.display-name="Python 3.11" \ - io.openshift.expose-services="8080:http" \ - io.openshift.tags="builder,python,python311,python-311,rh-python311" \ - com.redhat.component="python-311-container" \ - name="sclorg/python-311-minimal-c9s" \ - usage="s2i build https://github.com/sclorg/s2i-python-container.git --context-dir=3.11-minimal/test/setup-test-app/ ubi9/python-311-minimal python-sample-app" \ - com.redhat.license_terms="https://www.redhat.com/en/about/red-hat-end-user-license-agreements#UBI" \ - io.buildpacks.stack.id="com.redhat.stacks.ubi9-python-311-minimal" \ - maintainer="SoftwareCollections.org " - -# Very minimal set of packages -# Python is obvious in the Python container :) -# glibc-langpack-en is needed to set locale to en_US and disable warning about it -# findutils - find command is needed for fix-permissions script -# nss_wrapper - used in generate_container_user script -RUN INSTALL_PKGS="python3.11 glibc-langpack-en findutils nss_wrapper-libs" && \ - microdnf -y --setopt=tsflags=nodocs --setopt=install_weak_deps=0 install $INSTALL_PKGS && \ - microdnf -y clean all --enablerepo='*' - -# Copy the S2I scripts from the specific language image to $STI_SCRIPTS_PATH. -COPY 3.11-minimal/s2i/bin/ $STI_SCRIPTS_PATH - -# Copy extra files to the image. -COPY 3.11-minimal/root/ / - -# Python 3.7+ only -# Yes, the directory below is already copied by the previous command. -# The problem here is that the wheels directory is copied as a symlink. -# Only if you specify symlink directly as a source, COPY copies all the -# files from the symlink destination. -COPY 3.11-minimal/root/opt/wheels /opt/wheels - -# This command sets (and also creates if necessary) -# the home directory - it has to be done here so the latter -# fix-permissions fixes this directory as well. -WORKDIR ${HOME} - -# - Create a Python virtual environment for use by any application to avoid -# potential conflicts with Python packages preinstalled in the main Python -# installation. -# - In order to drop the root user, we have to make some directories world -# writable as OpenShift default security model is to run the container -# under random UID. -RUN \ - python3.11 -m venv ${APP_ROOT} && \ - # We have to upgrade pip to a newer version because \ - # pip < 19.3 does not support manylinux2014 wheels. Only manylinux2014 (and later) wheels \ - # support platforms like ppc64le, aarch64 or armv7 \ - # We are newly using wheel from one of the latest stable Fedora releases (from RPM python-pip-wheel) \ - # because it's tested better then whatever version from PyPI and contains useful patches. \ - # We have to do it here so the permissions are correctly fixed and pip is able \ - # to reinstall itself in the next build phases in the assemble script if user wants the latest version \ - ${APP_ROOT}/bin/pip install /opt/wheels/pip-* && \ - rm -r /opt/wheels && \ - chown -R 1001:0 ${APP_ROOT} && \ - fix-permissions ${APP_ROOT} -P && \ - rpm-file-permissions - -USER 1001 - -# Set the default CMD to print the usage of the language image. -CMD $STI_SCRIPTS_PATH/usage diff --git a/3.11-minimal/Dockerfile.rhel8 b/3.11-minimal/Dockerfile.rhel8 deleted file mode 100644 index f1cd8eb1..00000000 --- a/3.11-minimal/Dockerfile.rhel8 +++ /dev/null @@ -1,104 +0,0 @@ -FROM ubi8/ubi-minimal:latest - - -EXPOSE 8080 - -ENV PYTHON_VERSION=3.11 \ - PYTHONUNBUFFERED=1 \ - PYTHONIOENCODING=UTF-8 \ - LC_ALL=en_US.UTF-8 \ - LANG=en_US.UTF-8 \ - CNB_STACK_ID=com.redhat.stacks.ubi8-python-311 \ - CNB_USER_ID=1001 \ - CNB_GROUP_ID=0 \ - PIP_NO_CACHE_DIR=off \ - # The following variables are usually available from parent s2i images \ - STI_SCRIPTS_PATH=/usr/libexec/s2i \ - APP_ROOT=/opt/app-root \ - HOME=/opt/app-root/src \ - PLATFORM="el8" - -# /opt/app-root/bin - the main venv -# /opt/app-root/src/bin - app-specific binaries -# /opt/app-root/src/.local/bin - tools like pipenv -ENV PATH=$APP_ROOT/bin:$HOME/bin:$HOME/.local/bin:$PATH - -# Ensure the virtual environment is active in interactive shells -ENV BASH_ENV=${APP_ROOT}/bin/activate \ - ENV=${APP_ROOT}/bin/activate \ - PROMPT_COMMAND=". ${APP_ROOT}/bin/activate" - -ENV SUMMARY="Minimal platform for building and running Python $PYTHON_VERSION applications" \ - DESCRIPTION="Python $PYTHON_VERSION available as container is a base platform for \ -building and running various Python $PYTHON_VERSION applications and frameworks. \ -Python is an easy to learn, powerful programming language. It has efficient high-level \ -data structures and a simple but effective approach to object-oriented programming. \ -Python's elegant syntax and dynamic typing, together with its interpreted nature, \ -make it an ideal language for scripting and rapid application development in many areas \ -on most platforms." - -LABEL summary="$SUMMARY" \ - description="$DESCRIPTION" \ - io.k8s.description="$DESCRIPTION" \ - io.k8s.display-name="Python 3.11" \ - io.openshift.expose-services="8080:http" \ - io.openshift.tags="builder,python,python311,python-311,rh-python311" \ - com.redhat.component="python-311-container" \ - name="ubi8/python-311-minimal" \ - usage="s2i build https://github.com/sclorg/s2i-python-container.git --context-dir=3.11-minimal/test/setup-test-app/ ubi8/python-311-minimal python-sample-app" \ - com.redhat.license_terms="https://www.redhat.com/en/about/red-hat-end-user-license-agreements#UBI" \ - io.buildpacks.stack.id="com.redhat.stacks.ubi8-python-311-minimal" \ - maintainer="SoftwareCollections.org " - -# Very minimal set of packages -# Python is obvious in the Python container :) -# glibc-langpack-en is needed to set locale to en_US and disable warning about it -# findutils - find command is needed for fix-permissions script -# nss_wrapper - used in generate_container_user script -RUN INSTALL_PKGS="python3.11 glibc-langpack-en findutils nss_wrapper-libs" && \ - microdnf -y --setopt=tsflags=nodocs --setopt=install_weak_deps=0 install $INSTALL_PKGS && \ - microdnf -y clean all --enablerepo='*' - -# Copy the S2I scripts from the specific language image to $STI_SCRIPTS_PATH. -COPY 3.11-minimal/s2i/bin/ $STI_SCRIPTS_PATH - -# Copy extra files to the image. -COPY 3.11-minimal/root/ / - -# Python 3.7+ only -# Yes, the directory below is already copied by the previous command. -# The problem here is that the wheels directory is copied as a symlink. -# Only if you specify symlink directly as a source, COPY copies all the -# files from the symlink destination. -COPY 3.11-minimal/root/opt/wheels /opt/wheels - -# This command sets (and also creates if necessary) -# the home directory - it has to be done here so the latter -# fix-permissions fixes this directory as well. -WORKDIR ${HOME} - -# - Create a Python virtual environment for use by any application to avoid -# potential conflicts with Python packages preinstalled in the main Python -# installation. -# - In order to drop the root user, we have to make some directories world -# writable as OpenShift default security model is to run the container -# under random UID. -RUN \ - python3.11 -m venv ${APP_ROOT} && \ - # We have to upgrade pip to a newer version because \ - # pip < 19.3 does not support manylinux2014 wheels. Only manylinux2014 (and later) wheels \ - # support platforms like ppc64le, aarch64 or armv7 \ - # We are newly using wheel from one of the latest stable Fedora releases (from RPM python-pip-wheel) \ - # because it's tested better then whatever version from PyPI and contains useful patches. \ - # We have to do it here so the permissions are correctly fixed and pip is able \ - # to reinstall itself in the next build phases in the assemble script if user wants the latest version \ - ${APP_ROOT}/bin/pip install /opt/wheels/pip-* && \ - rm -r /opt/wheels && \ - chown -R 1001:0 ${APP_ROOT} && \ - fix-permissions ${APP_ROOT} -P && \ - rpm-file-permissions - -USER 1001 - -# Set the default CMD to print the usage of the language image. -CMD $STI_SCRIPTS_PATH/usage diff --git a/3.11-minimal/README.md b/3.11-minimal/README.md deleted file mode 100644 index e978131c..00000000 --- a/3.11-minimal/README.md +++ /dev/null @@ -1,123 +0,0 @@ -Python 3.11 container image - minimal version -============================================ - -This container image is a special version of the [full Python 3.11 container image](https://github.com/sclorg/s2i-python-container/tree/master/3.11) -provided as a [S2I](https://github.com/openshift/source-to-image) base image for your Python 3.11 applications. - -Because the minimal and full images work similarly, we document here only the differences and limitations -of the minimal container image. For the documentation of common features see the [full container image docs](https://github.com/sclorg/s2i-python-container/tree/master/3.11). - -The Python 3.11 minimal container image is currently considered a tech-preview and only available on quay.io. -The image is built on top of the [official CentOS Stream base containers](quay.io/centos/centos). - -To pull the Python 3.11 minimal container image to build on, run - -``` -podman pull quay.io/sclorg/python-311-minimal-c9s -``` - -Description ------------ - -The full container image is a universal base image to build your containerized applications on top of. However, its universal nature -means that the resulting containers it produces consume a lot of disk space. This is caused mainly by the fact that the image contains -npm, compilers, header files and some other packages one might need to install and deploy their applications. - -Because size does matter for us and our customers, we have prepared this minimal container image with very limited subset -of installed packages. There are no compilers, no header files, no npm etc and the yum package manager is replaced with a minimalistic -reimplementation called microdnf, making the resulting container images much smaller. This creates some limitations -but we provide ways to workaround them. - -Limitations ------------ - -1. There is only a very limited subset of packages installed. They are choosen carefully to satisfy most of the Python apps but your app might have some special needs. -1. There is no npm and nodejs. -1. There are no compilers and header files. Installation from Python wheels should still work but compilation from a source code is not supported out of the box. - -In the next chapter, we provide three possible workarounds for the mentioned limitations of the minimal container image. - -Possible solutions for the limitations --------------------------------------- - -### Use the full container image - -It's easy at that. If you don't want to write your own Dockerfile and disk space is not a problem, use -the full universal container image and you should be fine. - -### Build your own container image on top of the minimal container image - -Let's say that your application depends on uwsgi. uwsgi cannot be installed from Python wheel and has to be -compiled from source which requires some additional packages to be installed - namely gcc for the compilation -itself and python3.11-devel containing Python header files. - -To solve that problem, you can use all the pieces provided by the minimal container image and just add one more -step to install the missing dependencies: - -``` -FROM python-311-minimal - -# Add application sources to a directory that the assemble script expects them -# and set permissions so that the container runs without root access -USER 0 -ADD app-src /tmp/src -RUN /usr/bin/fix-permissions /tmp/src - -# Install packages necessary for compiling uwsgi from source -RUN microdnf install -y gcc python3.11-devel -USER 1001 - -# Install the dependencies -RUN /usr/libexec/s2i/assemble - -# Set the default command for the resulting image -CMD /usr/libexec/s2i/run -``` - -If you do it this way, your problem with the missing packages is solved. But there is also one disadvantage: the resulting -runtime image contains unnecessary compiler and Python header files. How to solve this? Uninstalling them at the end -of the Dockerfile is not really a solution but we have one. Keep reading. - -### Build on full image, run on minimal image - -Did you know that you can copy files from one image to another one during a build? That's the feature we are gonna use now. -We use the full container image with all compilers and other usefull packages installed to build our app and its dependencies -and we then move the result including the whole virtual environemnt to the minimal container image. - -This app needs mod_wsgi and to install (compile it from source) it, we'll need: httpd-devel for header files, gcc and redhat-rpm-config -as a compiler and configuratuion and finally python3.11-devel containing Python header files. There is no need to install those packages -manually because the full container image already contains them. However, the application needs httpd as a runtime dependency -so we need to install it to the minimal container image as well. - -``` -# Part 1 - build - -FROM python-311 as builder - -# Add application sources to a directory that the assemble script expects them -# and set permissions so that the container runs without root access -USER 0 -ADD app-src /tmp/src -RUN /usr/bin/fix-permissions /tmp/src -USER 1001 - -# Install the application's dependencies from PyPI -RUN /usr/libexec/s2i/assemble - -# Part 2 - deploy - -FROM python-311-minimal - -# Copy app sources together with the whole virtual environment from the builder image -COPY --from=builder $APP_ROOT $APP_ROOT - -# Install httpd package - runtime dependency of our application -USER 0 -RUN microdnf install -y httpd -USER 1001 - -# Set the default command for the resulting image -CMD /usr/libexec/s2i/run -``` - -This way, the resulting container image does contain only necessary dependencies and it's much lighter. diff --git a/3.11-minimal/root/opt/app-root/etc/generate_container_user b/3.11-minimal/root/opt/app-root/etc/generate_container_user deleted file mode 100644 index a7fd74d6..00000000 --- a/3.11-minimal/root/opt/app-root/etc/generate_container_user +++ /dev/null @@ -1,19 +0,0 @@ -# Set current user in nss_wrapper -USER_ID=$(id -u) -GROUP_ID=$(id -g) - -if [ x"$USER_ID" != x"0" -a x"$USER_ID" != x"1001" ]; then - - NSS_WRAPPER_PASSWD=/opt/app-root/etc/passwd - NSS_WRAPPER_GROUP=/etc/group - - cat /etc/passwd | sed -e 's/^default:/builder:/' > $NSS_WRAPPER_PASSWD - - echo "default:x:${USER_ID}:${GROUP_ID}:Default Application User:${HOME}:/bin/bash" >> $NSS_WRAPPER_PASSWD - - export NSS_WRAPPER_PASSWD - export NSS_WRAPPER_GROUP - - LD_PRELOAD=libnss_wrapper.so - export LD_PRELOAD -fi diff --git a/3.11-minimal/root/opt/wheels b/3.11-minimal/root/opt/wheels deleted file mode 120000 index 4eabc067..00000000 --- a/3.11-minimal/root/opt/wheels +++ /dev/null @@ -1 +0,0 @@ -../../../src/root/opt/wheels/ \ No newline at end of file diff --git a/3.11-minimal/root/usr/bin/cgroup-limits b/3.11-minimal/root/usr/bin/cgroup-limits deleted file mode 100755 index 6fa19153..00000000 --- a/3.11-minimal/root/usr/bin/cgroup-limits +++ /dev/null @@ -1,192 +0,0 @@ -#!/usr/libexec/platform-python - -""" -Script for parsing cgroup information - -This script will read some limits from the cgroup system and parse -them, printing out "VARIABLE=VALUE" on each line for every limit that is -successfully read. Output of this script can be directly fed into -bash's export command. Recommended usage from a bash script: - - set -o errexit - export_vars=$(cgroup-limits) ; export $export_vars - -Variables currently supported: - MAX_MEMORY_LIMIT_IN_BYTES - Maximum possible limit MEMORY_LIMIT_IN_BYTES can have. This is - currently constant value of 9223372036854775807. - MEMORY_LIMIT_IN_BYTES - Maximum amount of user memory in bytes. If this value is set - to the same value as MAX_MEMORY_LIMIT_IN_BYTES, it means that - there is no limit set. The value is taken from - /sys/fs/cgroup/memory/memory.limit_in_bytes for cgroups v1 - and from /sys/fs/cgroup/memory.max for cgroups v2 - NUMBER_OF_CORES - Number of CPU cores that can be used. If both the cpu and cpuset - controllers specify a limit, the controller with the lowest CPU - limit takes precedence. For the cpu controller, the value is - calculated from /sys/fs/cgroup/cpu/cpu.cfs_{quota,period}_us for - cgroups v1 and from /sys/fs/cgroup/cpuset.cpus.effective for cgroups v2. - For the cpuset controller, the value is taken from - /sys/fs/cgroup/cpuset/cpuset.cpus for cgroups v1 and from - /sys/fs/cgroup/cpuset.cpus.effective for cgroups v2 - NO_MEMORY_LIMIT - Set to "true" if MEMORY_LIMIT_IN_BYTES is so high that the caller - can act as if no memory limit was set. Undefined otherwise. - -Note about non-root containers: - - Per podman-run(1) man page, on some systems, changing the resource limits - may not be allowed for non-root users. For more details, see - https://github.com/containers/podman/blob/main/troubleshooting.md#26-running-containers-with-resource-limits-fails-with-a-permissions-error. - -How to test this script: - - Run a container as root and see whether the output of available memory - and CPUs match what is either available on the host or specified via - cgroups limits by the container runtime (podman). - - For example: - - # This should return NO_MEMORY_LIMIT=true, NUMBER_OF_CORES= - sudo podman run -ti --rm quay.io/fedora/s2i-core /usr/bin/cgroup-limits - - # This should return MEMORY_LIMIT_IN_BYTES=2147483648, NUMBER_OF_CORES=3 - # 3 CPUs despite --cpus 4 was given is correct, because the cpuset 2-4 means - # running on 3 concrete processors only, which is lower limit than --cpus - # and thus is preferred - sudo podman run -ti --rm --cpus 4 --cpuset-cpus=2-4 --memory 2G quay.io/fedora/s2i-core /usr/bin/cgroup-limits -""" - -from __future__ import division -from __future__ import print_function -import sys -import subprocess - - -def _read_file(path): - try: - with open(path, 'r') as f: - return f.read().strip() - except IOError: - return None - - -def get_memory_limit(): - """ - Read memory limit, in bytes. - """ - - limit = _read_file('/sys/fs/cgroup/memory/memory.limit_in_bytes') - # If first file does not exist, try cgroups v2 file - limit = limit or _read_file('/sys/fs/cgroup/memory.max') - if limit is None or not limit.isdigit(): - if limit == 'max': - return 9223372036854775807 - print("Warning: Can't detect memory limit from cgroups", - file=sys.stderr) - return None - return int(limit) - - -def get_number_of_cores(): - """ - Read number of CPU cores. - """ - - limits = [l for l in [_read_cpu_quota(), _read_cpuset_size(), _read_nproc()] if l] - if not limits: - return None - return min(limits) - - -def _read_cpu_quota(): - - quota, period = None, None - - quota = _read_file("/sys/fs/cgroup/cpu/cpu.cfs_quota_us") - if quota: - # cgroups v1 - quota = quota.strip() - if quota == "-1": - return None - - period = _read_file("/sys/fs/cgroup/cpu/cpu.cfs_period_us") - if period: - period = period.strip() - - else: - # cgroups v2 - line = _read_file("/sys/fs/cgroup/cpu.max") - if line: - fields = line.split() - - if len(fields) >= 2: - quota = fields[0] - if quota == "max": - return None - period = fields[1] - - - if quota and quota.isdigit() and period and period.isdigit(): - return int(quota)//int(period) - - print("Warning: Can't detect cpu quota from cgroups", - file=sys.stderr) - return None - - -def _read_cpuset_size(): - - core_count = 0 - - line = _read_file('/sys/fs/cgroup/cpuset/cpuset.cpus') - # If first file does not exist, try cgroups v2 file - line = line or _read_file('/sys/fs/cgroup/cpuset.cpus.effective') - if line is None: - # None of the files above exists when running podman as non-root, - # so in that case, this warning is printed every-time - print("Warning: Can't detect cpuset size from cgroups, will use nproc", - file=sys.stderr) - return None - - for group in line.split(','): - core_ids = list(map(int, group.split('-'))) - if len(core_ids) == 2: - core_count += core_ids[1] - core_ids[0] + 1 - else: - core_count += 1 - - return core_count - - -def _read_nproc(): - """ - Returns number of cores without looking at cgroup limits. - This might work as the last resort when running a container as non-root - where cgroups v2 resource limits cannot be set without a specific - configuration (per podman-run(1) man page). - """ - try: - stdout, stderr = subprocess.Popen('nproc', stdout=subprocess.PIPE).communicate() - return int(stdout) - except EnvironmentError as e: - if e.errno != errno.ENOENT: - raise - return None - - -if __name__ == "__main__": - env_vars = { - "MAX_MEMORY_LIMIT_IN_BYTES": 9223372036854775807, - "MEMORY_LIMIT_IN_BYTES": get_memory_limit(), - "NUMBER_OF_CORES": get_number_of_cores() - } - - env_vars = {k: v for k, v in env_vars.items() if v is not None} - - if env_vars.get("MEMORY_LIMIT_IN_BYTES", 0) >= 92233720368547: - env_vars["NO_MEMORY_LIMIT"] = "true" - - for key, value in env_vars.items(): - print("{0}={1}".format(key, value)) diff --git a/3.11-minimal/root/usr/bin/fix-permissions b/3.11-minimal/root/usr/bin/fix-permissions deleted file mode 100755 index ddd33ace..00000000 --- a/3.11-minimal/root/usr/bin/fix-permissions +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh - -# Allow this script to fail without failing a build -set +e - -SYMLINK_OPT=${2:--L} - -# Fix permissions on the given directory or file to allow group read/write of -# regular files and execute of directories. - -[ $(id -u) -ne 0 ] && CHECK_OWNER=" -uid $(id -u)" - -# If argument does not exist, script will still exit with 0, -# but at least we'll see something went wrong in the log -if ! [ -e "$1" ] ; then - echo "ERROR: File or directory $1 does not exist." >&2 - # We still want to end successfully - exit 0 -fi - -find $SYMLINK_OPT "$1" ${CHECK_OWNER} \! -gid 0 -exec chgrp 0 {} + -find $SYMLINK_OPT "$1" ${CHECK_OWNER} \! -perm -g+rw -exec chmod g+rw {} + -find $SYMLINK_OPT "$1" ${CHECK_OWNER} -perm /u+x -a \! -perm /g+x -exec chmod g+x {} + -find $SYMLINK_OPT "$1" ${CHECK_OWNER} -type d \! -perm /g+x -exec chmod g+x {} + - -# Always end successfully -exit 0 diff --git a/3.11-minimal/root/usr/bin/rpm-file-permissions b/3.11-minimal/root/usr/bin/rpm-file-permissions deleted file mode 100755 index 8be1fb0d..00000000 --- a/3.11-minimal/root/usr/bin/rpm-file-permissions +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -CHECK_DIRS="/ /opt /etc /usr /usr/bin /usr/lib /usr/lib64 /usr/share /usr/libexec" - -rpm_format="[%{FILESTATES:fstate} %7{FILEMODES:octal} %{FILENAMES:shescape}\n]" - -rpm -q --qf "$rpm_format" filesystem | while read line -do - eval "set -- $line" - - case $1 in - normal) ;; - *) continue ;; - esac - - case " $CHECK_DIRS " in - *" $3 "*) - chmod "${2: -4}" "$3" - ;; - esac -done diff --git a/3.11-minimal/s2i/bin/assemble b/3.11-minimal/s2i/bin/assemble deleted file mode 100755 index 15d2fbbd..00000000 --- a/3.11-minimal/s2i/bin/assemble +++ /dev/null @@ -1,134 +0,0 @@ -#!/bin/bash - -function is_django_installed() { - python -c "import django" &>/dev/null -} - -function should_collectstatic() { - is_django_installed && [[ -z "$DISABLE_COLLECTSTATIC" ]] -} - -function virtualenv_bin() { - # New versions of Python (>3.6) should use venv module - # from stdlib instead of virtualenv package - python3.11 -m venv $1 -} - -# Install pipenv or micropipenv to the separate virtualenv to isolate it -# from system Python packages and packages in the main -# virtualenv. Executable is simlinked into ~/.local/bin -# to be accessible. This approach is inspired by pipsi -# (pip script installer). -function install_tool() { - echo "---> Installing $1 packaging tool ..." - VENV_DIR=$HOME/.local/venvs/$1 - virtualenv_bin "$VENV_DIR" - # First, try to install the tool without --isolated which means that if you - # have your own PyPI mirror, it will take it from there. If this try fails, try it - # again with --isolated which ignores external pip settings (env vars, config file) - # and installs the tool from PyPI (needs internet connetion). - # $1$2 combines package name with [extras] or version specifier if is defined as $2``` - if ! $VENV_DIR/bin/pip install -U $1$2; then - echo "WARNING: Installation of $1 failed, trying again from official PyPI with pip --isolated install" - $VENV_DIR/bin/pip install --isolated -U $1$2 # Combines package name with [extras] or version specifier if is defined as $2``` - fi - mkdir -p $HOME/.local/bin - ln -s $VENV_DIR/bin/$1 $HOME/.local/bin/$1 -} - -set -e - -# First of all, check that we don't have disallowed combination of ENVs -if [[ ! -z "$ENABLE_PIPENV" && ! -z "$ENABLE_MICROPIPENV" ]]; then - echo "ERROR: Pipenv and micropipenv cannot be enabled at the same time!" - # podman/buildah does not relay this exit code but it will be fixed hopefuly - # https://github.com/containers/buildah/issues/2305 - exit 3 -fi - -shopt -s dotglob -echo "---> Installing application source ..." -mv /tmp/src/* "$HOME" - -# set permissions for any installed artifacts -fix-permissions /opt/app-root -P - - -if [[ ! -z "$PIP_INDEX_URL" ]]; then - echo "---> Creating pip.ini config file" - echo "[global] -index-url = $PIP_INDEX_URL" >> /opt/app-root/src/pip.ini -fi - -if [[ ! -z "$UPGRADE_PIP_TO_LATEST" ]]; then - echo "---> Upgrading pip, setuptools and wheel to latest version ..." - if ! pip install -U pip setuptools wheel; then - echo "WARNING: Installation of the latest pip, setuptools and wheel failed, trying again from official PyPI with pip --isolated install" - pip install --isolated -U pip setuptools wheel - fi -fi - -if [[ ! -z "$ENABLE_PIPENV" ]]; then - if [[ ! -z "$PIN_PIPENV_VERSION" ]]; then - # Add == as a prefix to pipenv version, if defined - PIN_PIPENV_VERSION="==$PIN_PIPENV_VERSION" - fi - install_tool "pipenv" "$PIN_PIPENV_VERSION" - echo "---> Installing dependencies via pipenv ..." - if [[ -f Pipfile ]]; then - pipenv install --deploy - elif [[ -f requirements.txt ]]; then - pipenv install -r requirements.txt - fi - # pipenv check -elif [[ ! -z "$ENABLE_MICROPIPENV" ]]; then - install_tool "micropipenv" "[toml]" - echo "---> Installing dependencies via micropipenv ..." - # micropipenv detects Pipfile.lock and requirements.txt in this order - micropipenv install --deploy -elif [[ -f requirements.txt ]]; then - echo "---> Installing dependencies ..." - pip install -r requirements.txt -fi - -if [[ ( -f setup.py || -f setup.cfg ) && -z "$DISABLE_SETUP_PY_PROCESSING" ]]; then - echo "---> Installing application (via setup.{py,cfg})..." - pip install . -fi - -if [[ -f pyproject.toml && -z "$DISABLE_PYPROJECT_TOML_PROCESSING" ]]; then - echo "---> Installing application (via pyproject.toml)..." - pip install . -fi - -if should_collectstatic; then - ( - echo "---> Collecting Django static files ..." - - APP_HOME=$(readlink -f "${APP_HOME:-.}") - # Change the working directory to APP_HOME - PYTHONPATH="$(pwd)${PYTHONPATH:+:$PYTHONPATH}" - cd "$APP_HOME" - - # Look for 'manage.py' in the current directory - manage_file=./manage.py - - if [[ ! -f "$manage_file" ]]; then - echo "WARNING: seems that you're using Django, but we could not find a 'manage.py' file." - echo "'manage.py collectstatic' ignored." - exit - fi - - if ! python $manage_file collectstatic --dry-run --noinput &> /dev/null; then - echo "WARNING: could not run 'manage.py collectstatic'. To debug, run:" - echo " $ python $manage_file collectstatic --noinput" - echo "Ignore this warning if you're not serving static files with Django." - exit - fi - - python $manage_file collectstatic --noinput - ) -fi - -# set permissions for any installed artifacts -fix-permissions /opt/app-root -P diff --git a/3.11-minimal/s2i/bin/init-wrapper b/3.11-minimal/s2i/bin/init-wrapper deleted file mode 100755 index 26c8767d..00000000 --- a/3.11-minimal/s2i/bin/init-wrapper +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -# Overview of how this script works: http://veithen.io/2014/11/16/sigterm-propagation.html -# Set a trap to kill the main app process when this -# init script receives SIGTERM or SIGINT -trap 'kill -s TERM $PID' TERM INT -# Execute the main application in the background -"$@" & -PID=$! -# wait command always terminates when trap is caught, even if the process hasn't finished yet -wait $PID -# Remove the trap and wait till the app process finishes completely -trap - TERM INT -# We wait again, since the first wait terminates when trap is caught -wait $PID -# Exit with the exit code of the app process -STATUS=$? -exit $STATUS diff --git a/3.11-minimal/s2i/bin/run b/3.11-minimal/s2i/bin/run deleted file mode 100755 index bc0b3a15..00000000 --- a/3.11-minimal/s2i/bin/run +++ /dev/null @@ -1,157 +0,0 @@ -#!/bin/bash -source /opt/app-root/etc/generate_container_user - -set -e - -function is_gunicorn_installed() { - hash gunicorn &>/dev/null -} - -function is_django_installed() { - python -c "import django" &>/dev/null -} - -function should_migrate() { - is_django_installed && [[ -z "$DISABLE_MIGRATE" ]] -} - -# Guess the number of workers according to the number of cores -function get_default_web_concurrency() { - # Using python and just python here because the script has - # platform-python in its shebang which we don't have in the minimal image - limit_vars=$(python /usr/bin/cgroup-limits) - local $limit_vars - if [ -z "${NUMBER_OF_CORES:-}" ]; then - echo 1 - return - fi - - local max=$((NUMBER_OF_CORES*2)) - # Require at least 43 MiB and additional 40 MiB for every worker - local default=$(((${MEMORY_LIMIT_IN_BYTES:-MAX_MEMORY_LIMIT_IN_BYTES}/1024/1024 - 43) / 40)) - default=$((default > max ? max : default)) - default=$((default < 1 ? 1 : default)) - # According to http://docs.gunicorn.org/en/stable/design.html#how-many-workers, - # 12 workers should be enough to handle hundreds or thousands requests per second - default=$((default > 12 ? 12 : default)) - echo $default -} - -function maybe_run_in_init_wrapper() { - if [[ -z "$ENABLE_INIT_WRAPPER" ]]; then - exec "$@" - else - exec $STI_SCRIPTS_PATH/init-wrapper "$@" - fi -} - -# Look for gunicorn>=20.1.0 to utilize gunicorn.conf.py -if is_gunicorn_installed && [[ -f "gunicorn.conf.py" ]]; then - ret=$(python -c 'import gunicorn -ver = gunicorn.version_info -print(0 if ver[0]>=21 or (ver[0] == 20 and ver[1] >= 1) else 1)') - grep -q "wsgi_app" gunicorn.conf.py && grep_result=0 || grep_result=1 - if [[ $ret -eq 0 ]] && [[ $grep_result -eq 0 ]]; then - echo "---> Using gunicorn.conf.py" - echo "---> Serving application with gunicorn ..." - exec gunicorn - fi -fi - -APP_HOME=$(readlink -f "${APP_HOME:-.}") -# Change the working directory to APP_HOME -PYTHONPATH="$(pwd)${PYTHONPATH:+:$PYTHONPATH}" -cd "$APP_HOME" - -if [ -z "$APP_SCRIPT" ] && [ -z "$APP_FILE" ] && [ -z "$APP_MODULE" ]; then - # Set default values for APP_SCRIPT and APP_FILE only when all three APP_ - # variables are not defined by user. This prevents a situation when - # APP_MODULE is defined to app:application but the app.py file is found as the - # APP_FILE and then executed by Python instead of gunicorn. - APP_SCRIPT="app.sh" - APP_SCRIPT_DEFAULT=1 - APP_FILE="app.py" - APP_FILE_DEFAULT=1 -fi - -if [ ! -z "$APP_SCRIPT" ]; then - if [[ -f "$APP_SCRIPT" ]]; then - echo "---> Running application from script ($APP_SCRIPT) ..." - if [[ "$APP_SCRIPT" != /* ]]; then - APP_SCRIPT="./$APP_SCRIPT" - fi - maybe_run_in_init_wrapper "$APP_SCRIPT" - elif [[ -z "$APP_SCRIPT_DEFAULT" ]]; then - echo "ERROR: file '$APP_SCRIPT' not found." && exit 1 - fi -fi - -if [ ! -z "$APP_FILE" ]; then - if [[ -f "$APP_FILE" ]]; then - echo "---> Running application from Python script ($APP_FILE) ..." - maybe_run_in_init_wrapper python "$APP_FILE" - elif [[ -z "$APP_FILE_DEFAULT" ]]; then - echo "ERROR: file '$APP_FILE' not found." && exit 1 - fi -fi - -# Look for 'manage.py' in the current directory -manage_file=./manage.py - -if should_migrate; then - if [[ -f "$manage_file" ]]; then - echo "---> Migrating database ..." - python "$manage_file" migrate --noinput - else - echo "WARNING: seems that you're using Django, but we could not find a 'manage.py' file." - echo "Skipped 'python manage.py migrate'." - fi -fi - -# If not set, use 8080 as the default port -if [ -z "$PORT" ]; then - PORT=8080 -fi - -if is_gunicorn_installed; then - setup_py=$(find "$HOME" -maxdepth 2 -type f -name 'setup.py' -print -quit) - # Look for wsgi module in the current directory - if [[ -z "$APP_MODULE" && -f "./wsgi.py" ]]; then - APP_MODULE=wsgi - elif [[ -z "$APP_MODULE" && -f "$setup_py" ]]; then - APP_MODULE="$(python "$setup_py" --name)" - fi - - if [[ "$APP_MODULE" ]]; then - export WEB_CONCURRENCY=${WEB_CONCURRENCY:-$(get_default_web_concurrency)} - - # Default settings for gunicorn if none of the custom are set - if [ -z "$APP_CONFIG" ] && [ -z "$GUNICORN_CMD_ARGS" ]; then - GUNICORN_CMD_ARGS="--bind=0.0.0.0:$PORT --access-logfile=-" - gunicorn_settings_source="default" - else - gunicorn_settings_source="custom" - fi - - # Gunicorn can read GUNICORN_CMD_ARGS as an env variable; we also pass them as - # arguments explicitly for compatibility with older Gunicorn versions. - echo "---> Serving application with gunicorn ($APP_MODULE) with $gunicorn_settings_source settings ..." - exec gunicorn "$APP_MODULE" $GUNICORN_CMD_ARGS --config "$APP_CONFIG" - fi -fi - -if is_django_installed; then - if [[ -f "$manage_file" ]]; then - echo "---> Serving application with 'manage.py runserver 0.0.0.0:$PORT' ..." - echo "WARNING: this is NOT a recommended way to run you application in production!" - echo "Consider using gunicorn or some other production web server." - maybe_run_in_init_wrapper python "$manage_file" runserver 0.0.0.0:$PORT - else - echo "WARNING: seems that you're using Django, but we could not find a 'manage.py' file." - echo "Skipped 'python manage.py runserver'." - fi -fi - ->&2 echo "ERROR: don't know how to run your application." ->&2 echo "Please set either APP_MODULE, APP_FILE or APP_SCRIPT environment variables, or create a file 'app.py' to launch your application." -exit 1 diff --git a/3.11-minimal/s2i/bin/usage b/3.11-minimal/s2i/bin/usage deleted file mode 100755 index b3ec4771..00000000 --- a/3.11-minimal/s2i/bin/usage +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -DISTRO=`cat /etc/*-release | grep ^ID= | grep -Po '".*?"' | tr -d '"'` -NAMESPACE=centos -[[ $DISTRO =~ rhel* ]] && NAMESPACE=rhscl - -cat < -- curl 127.0.0.1:8080 -EOF diff --git a/3.11-minimal/test/__init__.py b/3.11-minimal/test/__init__.py deleted file mode 120000 index d0f4746a..00000000 --- a/3.11-minimal/test/__init__.py +++ /dev/null @@ -1 +0,0 @@ -../../test/__init__.py \ No newline at end of file diff --git a/3.11-minimal/test/app-home-test-app b/3.11-minimal/test/app-home-test-app deleted file mode 120000 index f6b42e77..00000000 --- a/3.11-minimal/test/app-home-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/app-home-test-app \ No newline at end of file diff --git a/3.11-minimal/test/app-module-test-app b/3.11-minimal/test/app-module-test-app deleted file mode 120000 index fa20034b..00000000 --- a/3.11-minimal/test/app-module-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/app-module-test-app \ No newline at end of file diff --git a/3.11-minimal/test/check_imagestreams.py b/3.11-minimal/test/check_imagestreams.py deleted file mode 120000 index 56bb2be7..00000000 --- a/3.11-minimal/test/check_imagestreams.py +++ /dev/null @@ -1 +0,0 @@ -../../common/check_imagestreams.py \ No newline at end of file diff --git a/3.11-minimal/test/conftest.py b/3.11-minimal/test/conftest.py deleted file mode 120000 index 3f2d7840..00000000 --- a/3.11-minimal/test/conftest.py +++ /dev/null @@ -1 +0,0 @@ -../../test/conftest.py \ No newline at end of file diff --git a/3.11-minimal/test/django-different-port-test-app b/3.11-minimal/test/django-different-port-test-app deleted file mode 120000 index cc115af1..00000000 --- a/3.11-minimal/test/django-different-port-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/django-different-port-test-app \ No newline at end of file diff --git a/3.11-minimal/test/django-test-app b/3.11-minimal/test/django-test-app deleted file mode 120000 index 52cebf3b..00000000 --- a/3.11-minimal/test/django-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/django-test-app \ No newline at end of file diff --git a/3.11-minimal/test/from-dockerfile/mod_wsgi.Dockerfile.tpl b/3.11-minimal/test/from-dockerfile/mod_wsgi.Dockerfile.tpl deleted file mode 120000 index f5c5b907..00000000 --- a/3.11-minimal/test/from-dockerfile/mod_wsgi.Dockerfile.tpl +++ /dev/null @@ -1 +0,0 @@ -../../../src/test/from-dockerfile/mod_wsgi.Dockerfile.tpl \ No newline at end of file diff --git a/3.11-minimal/test/from-dockerfile/uwsgi.Dockerfile.tpl b/3.11-minimal/test/from-dockerfile/uwsgi.Dockerfile.tpl deleted file mode 100644 index a2f62783..00000000 --- a/3.11-minimal/test/from-dockerfile/uwsgi.Dockerfile.tpl +++ /dev/null @@ -1,20 +0,0 @@ -FROM #IMAGE_NAME# # Replaced by sed in ct_test_app_dockerfile - -ENV UPGRADE_PIP_TO_LATEST=1 - -# Add application sources to a directory that the assemble script expects them -# and set permissions so that the container runs without root access -USER 0 -ADD app-src /tmp/src -RUN /usr/bin/fix-permissions /tmp/src -# Install packages necessary for compiling uwsgi from source -# pkgconfig(python-3.11) is provided by both python3-devel in c9s -# and python3.11-devel in UBI8. -RUN microdnf install -y gcc "pkgconfig(python-3.11)" which -USER 1001 - -# Install the dependencies -RUN /usr/libexec/s2i/assemble - -# Set the default command for the resulting image -CMD /usr/libexec/s2i/run diff --git a/3.11-minimal/test/gunicorn-config-different-port-test-app b/3.11-minimal/test/gunicorn-config-different-port-test-app deleted file mode 120000 index c8eb6171..00000000 --- a/3.11-minimal/test/gunicorn-config-different-port-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/gunicorn-config-different-port-test-app \ No newline at end of file diff --git a/3.11-minimal/test/gunicorn-different-port-test-app b/3.11-minimal/test/gunicorn-different-port-test-app deleted file mode 120000 index 72c8e433..00000000 --- a/3.11-minimal/test/gunicorn-different-port-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/gunicorn-different-port-test-app \ No newline at end of file diff --git a/3.11-minimal/test/gunicorn-python-configfile-different-port-test-app b/3.11-minimal/test/gunicorn-python-configfile-different-port-test-app deleted file mode 120000 index 9139ee17..00000000 --- a/3.11-minimal/test/gunicorn-python-configfile-different-port-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/gunicorn-python-configfile-different-port-test-app \ No newline at end of file diff --git a/3.11-minimal/test/imagestreams b/3.11-minimal/test/imagestreams deleted file mode 120000 index 7a0aee9c..00000000 --- a/3.11-minimal/test/imagestreams +++ /dev/null @@ -1 +0,0 @@ -../../imagestreams \ No newline at end of file diff --git a/3.11-minimal/test/locale-test-app b/3.11-minimal/test/locale-test-app deleted file mode 120000 index 9105ec08..00000000 --- a/3.11-minimal/test/locale-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/locale-test-app \ No newline at end of file diff --git a/3.11-minimal/test/micropipenv-requirements-test-app b/3.11-minimal/test/micropipenv-requirements-test-app deleted file mode 120000 index cb2ddcf0..00000000 --- a/3.11-minimal/test/micropipenv-requirements-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/micropipenv-requirements-test-app \ No newline at end of file diff --git a/3.11-minimal/test/micropipenv-test-app/.gitignore b/3.11-minimal/test/micropipenv-test-app/.gitignore deleted file mode 100644 index ba746605..00000000 --- a/3.11-minimal/test/micropipenv-test-app/.gitignore +++ /dev/null @@ -1,57 +0,0 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] - -# C extensions -*.so - -# Distribution / packaging -.Python -env/ -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -*.egg-info/ -.installed.cfg -*.egg - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*,cover - -# Translations -*.mo -*.pot - -# Django stuff: -*.log - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ diff --git a/3.11-minimal/test/micropipenv-test-app/.s2i/environment b/3.11-minimal/test/micropipenv-test-app/.s2i/environment deleted file mode 100644 index 29efed4a..00000000 --- a/3.11-minimal/test/micropipenv-test-app/.s2i/environment +++ /dev/null @@ -1,5 +0,0 @@ -ENABLE_MICROPIPENV=true -DISABLE_SETUP_PY_PROCESSING=true -# This tests second try to install micropipenv with --isolated -# because the first one won't work with following setting -PIP_INDEX_URL=https://example.com/ diff --git a/3.11-minimal/test/micropipenv-test-app/Pipfile b/3.11-minimal/test/micropipenv-test-app/Pipfile deleted file mode 100644 index 9944bb52..00000000 --- a/3.11-minimal/test/micropipenv-test-app/Pipfile +++ /dev/null @@ -1,14 +0,0 @@ -[[source]] -url = "https://pypi.python.org/simple" -verify_ssl = true -name = "pypi" - -[packages] -"e1839a8" = {path = ".", editable = true} -requests = "==2.20.0" - -[dev-packages] -pytest = ">=2.8.0" - -[requires] -python_version = "3.11" diff --git a/3.11-minimal/test/micropipenv-test-app/Pipfile.lock b/3.11-minimal/test/micropipenv-test-app/Pipfile.lock deleted file mode 100644 index 7fc7c766..00000000 --- a/3.11-minimal/test/micropipenv-test-app/Pipfile.lock +++ /dev/null @@ -1,131 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "7ec65c8fa8465c6b96387fed7814980773c8c767f3aaf01fe836a222e763c7a0" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.11" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.python.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "certifi": { - "hashes": [ - "sha256:0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14", - "sha256:90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382" - ], - "markers": "python_version >= '3.6'", - "version": "==2022.9.24" - }, - "chardet": { - "hashes": [ - "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", - "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" - ], - "version": "==3.0.4" - }, - "e1839a8": { - "editable": true, - "path": "." - }, - "gunicorn": { - "hashes": [ - "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e", - "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8" - ], - "markers": "python_version >= '3.5'", - "version": "==20.1.0" - }, - "idna": { - "hashes": [ - "sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e", - "sha256:684a38a6f903c1d71d6d5fac066b58d7768af4de2b832e426ec79c30daa94a16" - ], - "version": "==2.7" - }, - "requests": { - "hashes": [ - "sha256:99dcfdaaeb17caf6e526f32b6a7b780461512ab3f1d992187801694cba42770c", - "sha256:a84b8c9ab6239b578f22d1c21d51b696dcfe004032bb80ea832398d6909d7279" - ], - "index": "pypi", - "version": "==2.20.0" - }, - "setuptools": { - "hashes": [ - "sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54", - "sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75" - ], - "markers": "python_version >= '3.7'", - "version": "==65.6.3" - }, - "testapp": { - "editable": true, - "path": "." - }, - "urllib3": { - "hashes": [ - "sha256:2393a695cd12afedd0dcb26fe5d50d0cf248e5a66f75dbd89a3d4eb333a61af4", - "sha256:a637e5fae88995b256e3409dc4d52c2e2e0ba32c42a6365fee8bbd2238de3cfb" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' and python_version < '4'", - "version": "==1.24.3" - } - }, - "develop": { - "attrs": { - "hashes": [ - "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6", - "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c" - ], - "markers": "python_version >= '3.5'", - "version": "==22.1.0" - }, - "iniconfig": { - "hashes": [ - "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3", - "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32" - ], - "version": "==1.1.1" - }, - "packaging": { - "hashes": [ - "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb", - "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522" - ], - "markers": "python_version >= '3.6'", - "version": "==21.3" - }, - "pluggy": { - "hashes": [ - "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159", - "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3" - ], - "markers": "python_version >= '3.6'", - "version": "==1.0.0" - }, - "pyparsing": { - "hashes": [ - "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb", - "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc" - ], - "markers": "python_full_version >= '3.6.8'", - "version": "==3.0.9" - }, - "pytest": { - "hashes": [ - "sha256:892f933d339f068883b6fd5a459f03d85bfcb355e4981e146d2c7616c21fef71", - "sha256:c4014eb40e10f11f355ad4e3c2fb2c6c6d1919c73f3b5a433de4708202cade59" - ], - "index": "pypi", - "version": "==7.2.0" - } - } -} diff --git a/3.11-minimal/test/micropipenv-test-app/setup.py b/3.11-minimal/test/micropipenv-test-app/setup.py deleted file mode 100644 index e3134094..00000000 --- a/3.11-minimal/test/micropipenv-test-app/setup.py +++ /dev/null @@ -1,10 +0,0 @@ -from setuptools import setup, find_packages - - -setup ( - name = "testapp", - version = "0.1", - description = "Example application to be deployed.", - packages = find_packages(), - install_requires = ["gunicorn"], -) diff --git a/3.11-minimal/test/micropipenv-test-app/testapp.py b/3.11-minimal/test/micropipenv-test-app/testapp.py deleted file mode 100644 index fe200352..00000000 --- a/3.11-minimal/test/micropipenv-test-app/testapp.py +++ /dev/null @@ -1,12 +0,0 @@ -import sys -import requests - - -def application(environ, start_response): - start_response('200 OK', [('Content-Type', 'text/plain')]) - # Python 3.12 needed requests version bump - if sys.version_info.major == 3 and sys.version_info.minor >= 12: - assert requests.__version__ == '2.28.2' - else: - assert requests.__version__ == '2.20.0' - return [b"Hello from gunicorn WSGI application!"] diff --git a/3.11-minimal/test/numpy-test-app b/3.11-minimal/test/numpy-test-app deleted file mode 120000 index b064f87f..00000000 --- a/3.11-minimal/test/numpy-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/numpy-test-app \ No newline at end of file diff --git a/3.11-minimal/test/pipenv-and-micropipenv-should-fail-test-app b/3.11-minimal/test/pipenv-and-micropipenv-should-fail-test-app deleted file mode 120000 index cf830645..00000000 --- a/3.11-minimal/test/pipenv-and-micropipenv-should-fail-test-app +++ /dev/null @@ -1 +0,0 @@ -../../src/test/pipenv-and-micropipenv-should-fail-test-app \ No newline at end of file diff --git a/3.11-minimal/test/pipenv-test-app/.gitignore b/3.11-minimal/test/pipenv-test-app/.gitignore deleted file mode 100644 index ba746605..00000000 --- a/3.11-minimal/test/pipenv-test-app/.gitignore +++ /dev/null @@ -1,57 +0,0 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] - -# C extensions -*.so - -# Distribution / packaging -.Python -env/ -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -*.egg-info/ -.installed.cfg -*.egg - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*,cover - -# Translations -*.mo -*.pot - -# Django stuff: -*.log - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ diff --git a/3.11-minimal/test/pipenv-test-app/.s2i/environment b/3.11-minimal/test/pipenv-test-app/.s2i/environment deleted file mode 100644 index 4a4f7605..00000000 --- a/3.11-minimal/test/pipenv-test-app/.s2i/environment +++ /dev/null @@ -1,2 +0,0 @@ -ENABLE_PIPENV=true -DISABLE_SETUP_PY_PROCESSING=true diff --git a/3.11-minimal/test/pipenv-test-app/Pipfile b/3.11-minimal/test/pipenv-test-app/Pipfile deleted file mode 100644 index 9944bb52..00000000 --- a/3.11-minimal/test/pipenv-test-app/Pipfile +++ /dev/null @@ -1,14 +0,0 @@ -[[source]] -url = "https://pypi.python.org/simple" -verify_ssl = true -name = "pypi" - -[packages] -"e1839a8" = {path = ".", editable = true} -requests = "==2.20.0" - -[dev-packages] -pytest = ">=2.8.0" - -[requires] -python_version = "3.11" diff --git a/3.11-minimal/test/pipenv-test-app/Pipfile.lock b/3.11-minimal/test/pipenv-test-app/Pipfile.lock deleted file mode 100644 index 7fc7c766..00000000 --- a/3.11-minimal/test/pipenv-test-app/Pipfile.lock +++ /dev/null @@ -1,131 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "7ec65c8fa8465c6b96387fed7814980773c8c767f3aaf01fe836a222e763c7a0" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.11" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.python.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "certifi": { - "hashes": [ - "sha256:0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14", - "sha256:90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382" - ], - "markers": "python_version >= '3.6'", - "version": "==2022.9.24" - }, - "chardet": { - "hashes": [ - "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", - "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" - ], - "version": "==3.0.4" - }, - "e1839a8": { - "editable": true, - "path": "." - }, - "gunicorn": { - "hashes": [ - "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e", - "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8" - ], - "markers": "python_version >= '3.5'", - "version": "==20.1.0" - }, - "idna": { - "hashes": [ - "sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e", - "sha256:684a38a6f903c1d71d6d5fac066b58d7768af4de2b832e426ec79c30daa94a16" - ], - "version": "==2.7" - }, - "requests": { - "hashes": [ - "sha256:99dcfdaaeb17caf6e526f32b6a7b780461512ab3f1d992187801694cba42770c", - "sha256:a84b8c9ab6239b578f22d1c21d51b696dcfe004032bb80ea832398d6909d7279" - ], - "index": "pypi", - "version": "==2.20.0" - }, - "setuptools": { - "hashes": [ - "sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54", - "sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75" - ], - "markers": "python_version >= '3.7'", - "version": "==65.6.3" - }, - "testapp": { - "editable": true, - "path": "." - }, - "urllib3": { - "hashes": [ - "sha256:2393a695cd12afedd0dcb26fe5d50d0cf248e5a66f75dbd89a3d4eb333a61af4", - "sha256:a637e5fae88995b256e3409dc4d52c2e2e0ba32c42a6365fee8bbd2238de3cfb" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' and python_version < '4'", - "version": "==1.24.3" - } - }, - "develop": { - "attrs": { - "hashes": [ - "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6", - "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c" - ], - "markers": "python_version >= '3.5'", - "version": "==22.1.0" - }, - "iniconfig": { - "hashes": [ - "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3", - "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32" - ], - "version": "==1.1.1" - }, - "packaging": { - "hashes": [ - "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb", - "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522" - ], - "markers": "python_version >= '3.6'", - "version": "==21.3" - }, - "pluggy": { - "hashes": [ - "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159", - "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3" - ], - "markers": "python_version >= '3.6'", - "version": "==1.0.0" - }, - "pyparsing": { - "hashes": [ - "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb", - "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc" - ], - "markers": "python_full_version >= '3.6.8'", - "version": "==3.0.9" - }, - "pytest": { - "hashes": [ - "sha256:892f933d339f068883b6fd5a459f03d85bfcb355e4981e146d2c7616c21fef71", - "sha256:c4014eb40e10f11f355ad4e3c2fb2c6c6d1919c73f3b5a433de4708202cade59" - ], - "index": "pypi", - "version": "==7.2.0" - } - } -} diff --git a/3.11-minimal/test/pipenv-test-app/setup.py b/3.11-minimal/test/pipenv-test-app/setup.py deleted file mode 100644 index e3134094..00000000 --- a/3.11-minimal/test/pipenv-test-app/setup.py +++ /dev/null @@ -1,10 +0,0 @@ -from setuptools import setup, find_packages - - -setup ( - name = "testapp", - version = "0.1", - description = "Example application to be deployed.", - packages = find_packages(), - install_requires = ["gunicorn"], -) diff --git a/3.11-minimal/test/pipenv-test-app/testapp.py b/3.11-minimal/test/pipenv-test-app/testapp.py deleted file mode 100644 index fe200352..00000000 --- a/3.11-minimal/test/pipenv-test-app/testapp.py +++ /dev/null @@ -1,12 +0,0 @@ -import sys -import requests - - -def application(environ, start_response): - start_response('200 OK', [('Content-Type', 'text/plain')]) - # Python 3.12 needed requests version bump - if sys.version_info.major == 3 and sys.version_info.minor >= 12: - assert requests.__version__ == '2.28.2' - else: - assert requests.__version__ == '2.20.0' - return [b"Hello from gunicorn WSGI application!"] diff --git a/3.11-minimal/test/poetry-src-layout-test-app b/3.11-minimal/test/poetry-src-layout-test-app deleted file mode 120000 index 92d2990d..00000000 --- a/3.11-minimal/test/poetry-src-layout-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/poetry-src-layout-test-app \ No newline at end of file diff --git a/3.11-minimal/test/pyuwsgi-pipenv-test-app/.s2i/environment b/3.11-minimal/test/pyuwsgi-pipenv-test-app/.s2i/environment deleted file mode 100644 index 9bfe6709..00000000 --- a/3.11-minimal/test/pyuwsgi-pipenv-test-app/.s2i/environment +++ /dev/null @@ -1,2 +0,0 @@ -ENABLE_PIPENV=1 -PIN_PIPENV_VERSION=2021.5.29 diff --git a/3.11-minimal/test/pyuwsgi-pipenv-test-app/app.sh b/3.11-minimal/test/pyuwsgi-pipenv-test-app/app.sh deleted file mode 100755 index 3a2680f2..00000000 --- a/3.11-minimal/test/pyuwsgi-pipenv-test-app/app.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -source .s2i/environment - -echo "Testing PIN_PIPENV_VERSION (set in .s2i/environment) ..." -pipenv_version=`pipenv --version` -expected="pipenv, version $PIN_PIPENV_VERSION" -if [ "$pipenv_version" != "$expected" ]; then - echo "ERROR: pipenv version is different than expected." - echo "Expected: ${expected}" - echo "Actual: ${pipenv_version}" - exit 1 -fi - -# Test the uwsgi server -exec uwsgi \ - --http-socket :8080 \ - --die-on-term \ - --master \ - --single-interpreter \ - --enable-threads \ - --threads=5 \ - --thunder-lock \ - --module wsgi diff --git a/3.11-minimal/test/pyuwsgi-pipenv-test-app/requirements.txt b/3.11-minimal/test/pyuwsgi-pipenv-test-app/requirements.txt deleted file mode 100644 index 932ba1d6..00000000 --- a/3.11-minimal/test/pyuwsgi-pipenv-test-app/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -pyuwsgi # this is just a copy of uwsgi project but it has wheels on PyPI -Flask diff --git a/3.11-minimal/test/pyuwsgi-pipenv-test-app/wsgi.py b/3.11-minimal/test/pyuwsgi-pipenv-test-app/wsgi.py deleted file mode 100644 index 96e1a614..00000000 --- a/3.11-minimal/test/pyuwsgi-pipenv-test-app/wsgi.py +++ /dev/null @@ -1,9 +0,0 @@ -from flask import Flask -application = Flask(__name__) - -@application.route('/') -def hello(): - return b'Hello World from uWSGI hosted WSGI application!' - -if __name__ == '__main__': - application.run() diff --git a/3.11-minimal/test/run b/3.11-minimal/test/run deleted file mode 100755 index 8de24fe3..00000000 --- a/3.11-minimal/test/run +++ /dev/null @@ -1,308 +0,0 @@ -#!/bin/bash -# -# The 'run' performs a simple test that verifies that S2I image. -# The main focus here is to excersise the S2I scripts. -# -# IMAGE_NAME specifies a name of the candidate image used for testing. -# The image has to be available before this script is executed. -# -declare -a COMMON_WEB_APPS=({gunicorn-config-different-port,gunicorn-different-port,django-different-port,standalone,setup,setup-requirements,django,numpy,app-home,locale,pipenv,pipenv-and-micropipenv-should-fail,app-module,pyuwsgi-pipenv,micropipenv,standalone-custom-pypi-index,gunicorn-python-configfile-different-port}-test-app) -declare -a FULL_WEB_APPS=({setup-cfg,npm-virtualenv-uwsgi,mod-wsgi,pin-pipenv-version,micropipenv-requirements,poetry-src-layout}-test-app) -declare -a MINIMAL_WEB_APPS=() -declare -a WEB_APPS=(${COMMON_WEB_APPS[@]} ${MINIMAL_WEB_APPS[@]}) - -# Some tests, like the one using the latest pipenv, might be unstable -# because new upstream releases tend to break our tests sometimes. -# If a test is in UNSTABLE_TESTS and IGNORE_UNSTABLE_TESTS env -# variable is defined, a result of the test has no impact on -# the overall result of the test suite. -# -# Reasons for specific tests to be marked as unstable: -# pipenv-test-app: -# - this testcase installs pipenv from the internet. -# Problem is that the upstream releases are from time-to-time broken -# which breaks this test. We generally want to know about it -# in upstream, but ignore this in downstream. -declare -a UNSTABLE_TESTS=(pipenv-test-app) - -# TODO: Make command compatible for Mac users -test_dir="$(readlink -f $(dirname "${BASH_SOURCE[0]}"))" -image_dir=$(readlink -f ${test_dir}/..) - -TEST_LIST="\ -test_s2i_usage -test_docker_run_usage -test_application -test_application_with_user -test_application_enable_init_wrapper -" - -TEST_VAR_DOCKER="\ -test_from_dockerfile_minimal -" - -if [[ -z $VERSION ]]; then - echo "ERROR: The VERSION variable must be set." - ct_check_testcase_result 1 - exit 1 -fi - -IMAGE_NAME=${IMAGE_NAME:-ubi9/python-${VERSION//./}} - -. test/test-lib.sh - -info() { - echo -e "\n\e[1m[INFO] $@\e[0m\n" -} - -image_exists() { - docker inspect $1 &>/dev/null -} - -container_exists() { - image_exists $(cat $cid_file) -} - - -container_ip() { - docker inspect --format="{{ .NetworkSettings.IPAddress }}" $(cat $cid_file) -} - -run_s2i_build() { - info "Building the ${1} application image ..." - ct_s2i_build_as_df file://${test_dir}/${1} ${IMAGE_NAME} ${IMAGE_NAME}-testapp ${s2i_args} -} - -prepare() { - if ! image_exists ${IMAGE_NAME}; then - echo "ERROR: The image ${IMAGE_NAME} must exist before this script is executed." - return 1 - fi - # TODO: S2I build require the application is a valid 'GIT' repository, we - # should remove this restriction in the future when a file:// is used. - info "Preparing to test ${1} ..." - pushd ${test_dir}/${1} >/dev/null - git init - git config user.email "build@localhost" && git config user.name "builder" - git add -A && git commit -m "Sample commit" - popd >/dev/null -} - -run_test_application() { - docker run --user=100001 ${CONTAINER_ARGS} --rm --cidfile=${cid_file} ${IMAGE_NAME}-testapp -} - -cleanup() { - info "Cleaning up the test application image" - if image_exists ${IMAGE_NAME}-testapp; then - docker rmi -f ${IMAGE_NAME}-testapp - fi - rm -rf ${test_dir}/${1}/.git -} -wait_for_cid() { - local max_attempts=10 - local sleep_time=1 - local attempt=1 - info "Waiting for application container to start $CONTAINER_ARGS ..." - while [ $attempt -le $max_attempts ]; do - [ -f $cid_file ] && [ -s $cid_file ] && return 0 - attempt=$(( $attempt + 1 )) - sleep $sleep_time - done - return 1 -} - -test_s2i_usage() { - info "Testing 's2i usage' ..." - ct_s2i_usage ${IMAGE_NAME} ${s2i_args} 1>/dev/null -} - -test_docker_run_usage() { - info "Testing 'docker run' usage ..." - docker run --rm ${IMAGE_NAME} &>/dev/null -} - -test_scl_usage() { - local run_cmd="$1" - local expected="$2" - local cid_file="$3" - - info "Testing command availability in the image" - out=$(docker run --rm ${IMAGE_NAME} /bin/bash -c "${run_cmd}" 2>&1) - if ! echo "${out}" | grep -q "${expected}"; then - echo "ERROR[/bin/bash -c "${run_cmd}"] Expected '${expected}', got '${out}'" - return 1 - fi - out=$(docker exec $(cat ${cid_file}) /bin/bash -c "${run_cmd}" 2>&1) - if ! echo "${out}" | grep -q "${expected}"; then - echo "ERROR[exec /bin/bash -c "${run_cmd}"] Expected '${expected}', got '${out}'" - return 1 - fi - out=$(docker exec $(cat ${cid_file}) /bin/sh -ic "${run_cmd}" 2>&1) - if ! echo "${out}" | grep -q "${expected}"; then - echo "ERROR[exec /bin/sh -ic "${run_cmd}"] Expected '${expected}', got '${out}'" - return 1 - fi -} - -test_connection() { - info "Testing the HTTP connection (http://$(container_ip):${test_port}) ${CONTAINER_ARGS} ..." - local max_attempts=30 - local sleep_time=1 - local attempt=1 - local result=1 - while [ $attempt -le $max_attempts ]; do - response_code=$(curl -s -w %{http_code} -o /dev/null http://$(container_ip):${test_port}/) - status=$? - if [ $status -eq 0 ]; then - if [ $response_code -eq 200 ]; then - result=0 - fi - break - fi - attempt=$(( $attempt + 1 )) - sleep $sleep_time - done - return $result -} - -test_application() { - local cid_file="$CID_FILE_DIR"/"$(mktemp -u -p . --suffix .cid)" - # Verify that the HTTP connection can be established to test application container - run_test_application & - - # Wait for the container to write it's CID file - wait_for_cid - # Some test apps have tests in their startup code so we have to check - # that the container starts at all - ct_check_testcase_result $? - - # Instead of relying on VERSION variable coming from Makefile - # set the expected string based on the PYTHON_VERSION defined - # inside the running container. - python_version=$(docker run --rm $IMAGE_NAME /bin/bash -c "echo \$PYTHON_VERSION" 2>&1) - - test_scl_usage "python --version" "Python $python_version." "${cid_file}" - ct_check_testcase_result $? - test_connection - ct_check_testcase_result $? - container_exists && docker stop $(cat "$cid_file") -} - -test_from_dockerfile(){ - info "Test from Dockerfile" - # Django 4.2 supports Python 3.9+ - django_example_repo_url="https://github.com/sclorg/django-ex.git@4.2.x" - - ct_test_app_dockerfile $test_dir/from-dockerfile/Dockerfile.tpl $django_example_repo_url 'Welcome to your Django application on OpenShift' app-src - ct_check_testcase_result $? - - info "Test from Dockerfile with no s2i scripts used" - ct_test_app_dockerfile $test_dir/from-dockerfile/Dockerfile_no_s2i.tpl $django_example_repo_url 'Welcome to your Django application on OpenShift' app-src - ct_check_testcase_result $? -} - -test_from_dockerfile_minimal(){ - info "Test from Dockerfile" - - # The following tests are for multi-stage builds. These technically also work on full images, but there is no reason to do multi-stage builds with full images. - - # uwsgi in uwsgi-test-app - ct_test_app_dockerfile $test_dir/from-dockerfile/uwsgi.Dockerfile.tpl $test_dir/uwsgi-test-app 'Hello World from uWSGI hosted WSGI application!' app-src - ct_check_testcase_result $? - - # So far, for all the minimal images, the name of the full container image counterpart - # is the same just without -minimal infix. - # sclorg/python-39-minimal-c9s / sclorg/python-39-c9s - # ubi8/python-39-minimal / ubi8/python-39 - FULL_IMAGE_NAME=${IMAGE_NAME/-minimal/} - - if ct_pull_image "$FULL_IMAGE_NAME"; then - # mod_wsgi in micropipenv-requirements-test-app - sed "s@#IMAGE_NAME#@${IMAGE_NAME}@;s@#FULL_IMAGE_NAME#@${FULL_IMAGE_NAME}@" $test_dir/from-dockerfile/mod_wsgi.Dockerfile.tpl > $test_dir/from-dockerfile/Dockerfile - ct_test_app_dockerfile $test_dir/from-dockerfile/Dockerfile $test_dir/micropipenv-requirements-test-app 'Hello World from mod_wsgi hosted WSGI application!' app-src - ct_check_testcase_result $? - else - echo "[SKIP] Multistage build from Dockerfile - $FULL_IMAGE_NAME does not exists." - fi - -} - -test_application_with_user() { - # test application with random user - CONTAINER_ARGS="--user 12345" test_application - -} - -test_application_enable_init_wrapper() { - # test application with init wrapper - CONTAINER_ARGS="-e ENABLE_INIT_WRAPPER=true" test_application -} - -# Positive test & non-zero exit status = ERROR. -# Negative test & zero exit status = ERROR. -# Tests with '-should-fail-' in their name should fail during a build, -# expecting non-zero exit status. -evaluate_build_result() { - local _result="$1" - local _app="$2" - local _type="positive" - local _test_msg="[PASSED]" - local _ret_code=0 - - if [[ "$_app" == *"-should-fail-"* ]]; then - _type="negative" - fi - - if [[ "$_type" == "positive" && "$_result" != "0" ]]; then - info "TEST FAILED (${_type}), EXPECTED:0 GOT:${_result}" - _ret_code=$_result - elif [[ "$_type" == "negative" && "$_result" == "0" ]]; then - info "TEST FAILED (${_type}), EXPECTED: non-zero GOT:${_result}" - _ret_code=1 - fi - if [ $_ret_code != 0 ]; then - cleanup - TESTSUITE_RESULT=1 - _test_msg="[FAILED]" - fi - ct_update_test_result "$_test_msg" "$_app" run_s2i_build - - if [[ "$_type" == "negative" && "$_result" != "0" ]]; then - _ret_code=127 # even though this is success, the app is still not built - fi - return $_ret_code -} - -ct_init - -# For debugging purposes, this script can be run with one or more arguments -# those arguments list is a sub-set of values in the WEB_APPS array defined above -# Example: ./run app-home-test-app pipenv-test-app -for app in ${@:-${WEB_APPS[@]}}; do - # Since we built the candidate image locally, we don't want S2I attempt to pull - # it from Docker hub - s2i_args="--pull-policy=never" - - # Example apps with "-different-port-" in their name don't use the default port 8080 - if [[ "$app" == *"-different-port-"* ]]; then - test_port=8085 - else - test_port=8080 - fi - - prepare ${app} - if [ $? -ne 0 ]; then - ct_update_test_result "[FAILED]" "${app}" "preparation" - TESTSUITE_RESULT=1 - continue - fi - run_s2i_build ${app} - evaluate_build_result $? "$app" || continue - - TEST_SET=${TESTS:-$TEST_LIST} ct_run_tests_from_testset "${app}" - - cleanup ${app} -done - -TEST_SET=${TESTS:-$TEST_VAR_DOCKER} ct_run_tests_from_testset "var-docker" diff --git a/3.11-minimal/test/run-openshift-pytest b/3.11-minimal/test/run-openshift-pytest deleted file mode 120000 index 5063ae30..00000000 --- a/3.11-minimal/test/run-openshift-pytest +++ /dev/null @@ -1 +0,0 @@ -../../test/run-openshift-pytest \ No newline at end of file diff --git a/3.11-minimal/test/run-pytest b/3.11-minimal/test/run-pytest deleted file mode 100755 index 9810fe89..00000000 --- a/3.11-minimal/test/run-pytest +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -# -# IMAGE_NAME specifies a name of the candidate image used for testing. -# The image has to be available before this script is executed. -# SINGLE_VERSION specifies the major version of the MariaDB in format of X.Y -# OS specifies RHEL version (e.g. OS=rhel8) -# - -THISDIR=$(dirname ${BASH_SOURCE[0]}) - -if python3 -c 'import sys; sys.exit(0 if sys.version_info < (3,13) else 1)'; then - PYTHON_VERSION="3.12" -else - PYTHON_VERSION="3" -fi -cd "${THISDIR}" && "python${PYTHON_VERSION}" -m pytest -s -rA --showlocals -vv test_container_*.py diff --git a/3.11-minimal/test/setup-cfg-test-app b/3.11-minimal/test/setup-cfg-test-app deleted file mode 120000 index 71a2b0cb..00000000 --- a/3.11-minimal/test/setup-cfg-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/setup-cfg-test-app \ No newline at end of file diff --git a/3.11-minimal/test/setup-requirements-test-app b/3.11-minimal/test/setup-requirements-test-app deleted file mode 120000 index c909ccb9..00000000 --- a/3.11-minimal/test/setup-requirements-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/setup-requirements-test-app \ No newline at end of file diff --git a/3.11-minimal/test/setup-test-app b/3.11-minimal/test/setup-test-app deleted file mode 120000 index 1b49f26f..00000000 --- a/3.11-minimal/test/setup-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/setup-test-app \ No newline at end of file diff --git a/3.11-minimal/test/standalone-custom-pypi-index-test-app b/3.11-minimal/test/standalone-custom-pypi-index-test-app deleted file mode 120000 index 12941a9a..00000000 --- a/3.11-minimal/test/standalone-custom-pypi-index-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/standalone-custom-pypi-index-test-app \ No newline at end of file diff --git a/3.11-minimal/test/standalone-test-app b/3.11-minimal/test/standalone-test-app deleted file mode 120000 index 3f158948..00000000 --- a/3.11-minimal/test/standalone-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/standalone-test-app \ No newline at end of file diff --git a/3.11-minimal/test/test-lib.sh b/3.11-minimal/test/test-lib.sh deleted file mode 120000 index 1ac99b93..00000000 --- a/3.11-minimal/test/test-lib.sh +++ /dev/null @@ -1 +0,0 @@ -../../common/test-lib.sh \ No newline at end of file diff --git a/3.11-minimal/test/test_container_application.py b/3.11-minimal/test/test_container_application.py deleted file mode 120000 index 25c1c1ec..00000000 --- a/3.11-minimal/test/test_container_application.py +++ /dev/null @@ -1 +0,0 @@ -../../test/test_container_application.py \ No newline at end of file diff --git a/3.11-minimal/test/test_container_basics.py b/3.11-minimal/test/test_container_basics.py deleted file mode 120000 index b85dc139..00000000 --- a/3.11-minimal/test/test_container_basics.py +++ /dev/null @@ -1 +0,0 @@ -../../test/test_container_basics.py \ No newline at end of file diff --git a/3.11-minimal/test/test_ocp_deploy_templates.py b/3.11-minimal/test/test_ocp_deploy_templates.py deleted file mode 120000 index 0b821390..00000000 --- a/3.11-minimal/test/test_ocp_deploy_templates.py +++ /dev/null @@ -1 +0,0 @@ -../../test/test_ocp_deploy_templates.py \ No newline at end of file diff --git a/3.11-minimal/test/test_ocp_helm_python_django_app.py b/3.11-minimal/test/test_ocp_helm_python_django_app.py deleted file mode 120000 index 34b4f0dd..00000000 --- a/3.11-minimal/test/test_ocp_helm_python_django_app.py +++ /dev/null @@ -1 +0,0 @@ -../../test/test_ocp_helm_python_django_app.py \ No newline at end of file diff --git a/3.11-minimal/test/test_ocp_helm_python_django_psql_persistent.py b/3.11-minimal/test/test_ocp_helm_python_django_psql_persistent.py deleted file mode 120000 index 64d2105d..00000000 --- a/3.11-minimal/test/test_ocp_helm_python_django_psql_persistent.py +++ /dev/null @@ -1 +0,0 @@ -../../test/test_ocp_helm_python_django_psql_persistent.py \ No newline at end of file diff --git a/3.11-minimal/test/test_ocp_helm_python_imagestreams.py b/3.11-minimal/test/test_ocp_helm_python_imagestreams.py deleted file mode 120000 index 0022607f..00000000 --- a/3.11-minimal/test/test_ocp_helm_python_imagestreams.py +++ /dev/null @@ -1 +0,0 @@ -../../test/test_ocp_helm_python_imagestreams.py \ No newline at end of file diff --git a/3.11-minimal/test/test_ocp_imagestreams_quickstart.py b/3.11-minimal/test/test_ocp_imagestreams_quickstart.py deleted file mode 120000 index 18f8d7e2..00000000 --- a/3.11-minimal/test/test_ocp_imagestreams_quickstart.py +++ /dev/null @@ -1 +0,0 @@ -../../test/test_ocp_imagestreams_quickstart.py \ No newline at end of file diff --git a/3.11-minimal/test/test_ocp_python_ex_standalone.py b/3.11-minimal/test/test_ocp_python_ex_standalone.py deleted file mode 120000 index bb6022f7..00000000 --- a/3.11-minimal/test/test_ocp_python_ex_standalone.py +++ /dev/null @@ -1 +0,0 @@ -../../test/test_ocp_python_ex_standalone.py \ No newline at end of file diff --git a/3.11-minimal/test/test_ocp_python_ex_template.py b/3.11-minimal/test/test_ocp_python_ex_template.py deleted file mode 120000 index b75080ca..00000000 --- a/3.11-minimal/test/test_ocp_python_ex_template.py +++ /dev/null @@ -1 +0,0 @@ -../../test/test_ocp_python_ex_template.py \ No newline at end of file diff --git a/3.11-minimal/test/uwsgi-test-app b/3.11-minimal/test/uwsgi-test-app deleted file mode 120000 index c3ccf241..00000000 --- a/3.11-minimal/test/uwsgi-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/uwsgi-test-app \ No newline at end of file diff --git a/3.11/Dockerfile.c9s b/3.11/Dockerfile.c9s deleted file mode 100644 index c6e42641..00000000 --- a/3.11/Dockerfile.c9s +++ /dev/null @@ -1,89 +0,0 @@ -# This image provides a Python 3.11 environment you can use to run your Python -# applications. -FROM quay.io/sclorg/s2i-base-c9s:c9s - -EXPOSE 8080 - -ENV PYTHON_VERSION=3.11 \ - PATH=$HOME/.local/bin/:$PATH \ - PYTHONUNBUFFERED=1 \ - PYTHONIOENCODING=UTF-8 \ - LC_ALL=en_US.UTF-8 \ - LANG=en_US.UTF-8 \ - PIP_NO_CACHE_DIR=off - -ENV NAME=python3 \ - ARCH=x86_64 - -ENV SUMMARY="Platform for building and running Python $PYTHON_VERSION applications" \ - DESCRIPTION="Python $PYTHON_VERSION available as container is a base platform for \ -building and running various Python $PYTHON_VERSION applications and frameworks. \ -Python is an easy to learn, powerful programming language. It has efficient high-level \ -data structures and a simple but effective approach to object-oriented programming. \ -Python's elegant syntax and dynamic typing, together with its interpreted nature, \ -make it an ideal language for scripting and rapid application development in many areas \ -on most platforms." - -LABEL summary="$SUMMARY" \ - description="$DESCRIPTION" \ - io.k8s.description="$DESCRIPTION" \ - io.k8s.display-name="Python 3.11" \ - io.openshift.expose-services="8080:http" \ - io.openshift.tags="builder,python,python311,python-311,rh-python311" \ - com.redhat.component="$NAME" \ - name="sclorg/python-311-c9s" \ - usage="s2i build https://github.com/sclorg/s2i-python-container.git --context-dir=3.11/test/setup-test-app/ $FGC/$NAME python-sample-app" \ - maintainer="SoftwareCollections.org " - -RUN INSTALL_PKGS="python3.11 python3.11-devel python3.11-pip nss_wrapper-libs httpd \ - httpd-devel mod_ssl mod_auth_gssapi mod_ldap mod_session \ - atlas-devel gcc-gfortran libffi-devel libtool-ltdl enchant \ - krb5-devel" && \ - yum -y --setopt=tsflags=nodocs install $INSTALL_PKGS && \ - rpm -V $INSTALL_PKGS && \ - yum -y clean all --enablerepo='*' - -# Copy the S2I scripts from the specific language image to $STI_SCRIPTS_PATH. -COPY 3.11/s2i/bin/ $STI_SCRIPTS_PATH - -# Copy extra files to the image. -COPY 3.11/root/ / - -# Python 3.7+ only -# Yes, the directory below is already copied by the previous command. -# The problem here is that the wheels directory is copied as a symlink. -# Only if you specify symlink directly as a source, COPY copies all the -# files from the symlink destination. -COPY 3.11/root/opt/wheels /opt/wheels -# - Create a Python virtual environment for use by any application to avoid -# potential conflicts with Python packages preinstalled in the main Python -# installation. -# - In order to drop the root user, we have to make some directories world -# writable as OpenShift default security model is to run the container -# under random UID. -RUN python3.11 -m venv ${APP_ROOT} && \ -# Python 3.7+ only code, Python <3.7 installs pip from PyPI in the assemble script. \ -# We have to upgrade pip to a newer verison because \ -# pip < 19.3 does not support manylinux2014 wheels. Only manylinux2014 (and later) wheels \ -# support platforms like ppc64le, aarch64 or armv7 \ -# We are newly using wheel from one of the latest stable Fedora releases (from RPM python-pip-wheel) \ -# because it's tested better then whatever version from PyPI and contains useful patches. \ -# We have to do it here (in the macro) so the permissions are correctly fixed and pip is able \ -# to reinstall itself in the next build phases in the assemble script if user wants the latest version \ -${APP_ROOT}/bin/pip install /opt/wheels/pip-* && \ -rm -r /opt/wheels && \ -chown -R 1001:0 ${APP_ROOT} && \ -fix-permissions ${APP_ROOT} -P && \ -# The following echo adds the unset command for the variables set below to the \ -# venv activation script. This prevents the virtual environment from being \ -# activated multiple times and also every time the prompt is rendered. \ -echo "unset BASH_ENV PROMPT_COMMAND ENV" >> ${APP_ROOT}/bin/activate -# Ensure the virtualenv is activated in interactive shells -ENV BASH_ENV="${APP_ROOT}/bin/activate" \ - ENV="${APP_ROOT}/bin/activate" \ - PROMPT_COMMAND=". ${APP_ROOT}/bin/activate" - -USER 1001 - -# Set the default CMD to print the usage of the language image. -CMD $STI_SCRIPTS_PATH/usage diff --git a/3.11/Dockerfile.rhel8 b/3.11/Dockerfile.rhel8 deleted file mode 100644 index 8b44ea74..00000000 --- a/3.11/Dockerfile.rhel8 +++ /dev/null @@ -1,96 +0,0 @@ -# This image provides a Python 3.11 environment you can use to run your Python -# applications. -FROM ubi8/s2i-base:1 - -EXPOSE 8080 - -ENV PYTHON_VERSION=3.11 \ - PATH=$HOME/.local/bin/:$PATH \ - PYTHONUNBUFFERED=1 \ - PYTHONIOENCODING=UTF-8 \ - LC_ALL=en_US.UTF-8 \ - LANG=en_US.UTF-8 \ - CNB_STACK_ID=com.redhat.stacks.ubi8-python-311 \ - CNB_USER_ID=1001 \ - CNB_GROUP_ID=0 \ - PIP_NO_CACHE_DIR=off - -ENV SUMMARY="Platform for building and running Python $PYTHON_VERSION applications" \ - DESCRIPTION="Python $PYTHON_VERSION available as container is a base platform for \ -building and running various Python $PYTHON_VERSION applications and frameworks. \ -Python is an easy to learn, powerful programming language. It has efficient high-level \ -data structures and a simple but effective approach to object-oriented programming. \ -Python's elegant syntax and dynamic typing, together with its interpreted nature, \ -make it an ideal language for scripting and rapid application development in many areas \ -on most platforms." - -LABEL summary="$SUMMARY" \ - description="$DESCRIPTION" \ - io.k8s.description="$DESCRIPTION" \ - io.k8s.display-name="Python 3.11" \ - io.openshift.expose-services="8080:http" \ - io.openshift.tags="builder,python,python311,python-311,rh-python311" \ - com.redhat.component="python-311-container" \ - name="ubi8/python-311" \ - usage="s2i build https://github.com/sclorg/s2i-python-container.git --context-dir=3.11/test/setup-test-app/ ubi8/python-311 python-sample-app" \ - com.redhat.license_terms="https://www.redhat.com/en/about/red-hat-end-user-license-agreements#UBI" \ - io.buildpacks.stack.id="com.redhat.stacks.ubi8-python-311" \ - maintainer="SoftwareCollections.org " - -RUN INSTALL_PKGS="python3.11 python3.11-devel python3.11-setuptools python3.11-pip nss_wrapper-libs \ - httpd httpd-devel mod_ssl mod_auth_gssapi mod_ldap \ - mod_session atlas-devel gcc-gfortran libffi-devel libtool-ltdl \ - enchant krb5-devel" && \ - yum -y module enable httpd:2.4 && \ - yum -y --setopt=tsflags=nodocs install $INSTALL_PKGS && \ - rpm -V $INSTALL_PKGS && \ - # Remove redhat-logos-httpd (httpd dependency) to keep image size smaller. - rpm -e --nodeps redhat-logos-httpd && \ - yum -y clean all --enablerepo='*' - -# Copy the S2I scripts from the specific language image to $STI_SCRIPTS_PATH. -COPY 3.11/s2i/bin/ $STI_SCRIPTS_PATH - -# Copy extra files to the image. -COPY 3.11/root/ / - -# Python 3.7+ only -# Yes, the directory below is already copied by the previous command. -# The problem here is that the wheels directory is copied as a symlink. -# Only if you specify symlink directly as a source, COPY copies all the -# files from the symlink destination. -COPY 3.11/root/opt/wheels /opt/wheels -# - Create a Python virtual environment for use by any application to avoid -# potential conflicts with Python packages preinstalled in the main Python -# installation. -# - In order to drop the root user, we have to make some directories world -# writable as OpenShift default security model is to run the container -# under random UID. -RUN \ - python3.11 -m venv ${APP_ROOT} && \ - # Python 3.7+ only code, Python <3.7 installs pip from PyPI in the assemble script. \ - # We have to upgrade pip to a newer verison because \ - # pip < 19.3 does not support manylinux2014 wheels. Only manylinux2014 (and later) wheels \ - # support platforms like ppc64le, aarch64 or armv7 \ - # We are newly using wheel from one of the latest stable Fedora releases (from RPM python-pip-wheel) \ - # because it's tested better then whatever version from PyPI and contains useful patches. \ - # We have to do it here (in the macro) so the permissions are correctly fixed and pip is able \ - # to reinstall itself in the next build phases in the assemble script if user wants the latest version \ - ${APP_ROOT}/bin/pip install /opt/wheels/pip-* && \ - rm -r /opt/wheels && \ - chown -R 1001:0 ${APP_ROOT} && \ - fix-permissions ${APP_ROOT} -P && \ - rpm-file-permissions && \ - # The following echo adds the unset command for the variables set below to the \ - # venv activation script. This prevents the virtual environment from being \ - # activated multiple times and also every time the prompt is rendered. \ - echo "unset BASH_ENV PROMPT_COMMAND ENV" >> ${APP_ROOT}/bin/activate -# Ensure the virtualenv is activated in interactive shells -ENV BASH_ENV="${APP_ROOT}/bin/activate" \ - ENV="${APP_ROOT}/bin/activate" \ - PROMPT_COMMAND=". ${APP_ROOT}/bin/activate" - -USER 1001 - -# Set the default CMD to print the usage of the language image. -CMD $STI_SCRIPTS_PATH/usage diff --git a/3.11/Dockerfile.rhel9 b/3.11/Dockerfile.rhel9 deleted file mode 100644 index 5c9d1f2c..00000000 --- a/3.11/Dockerfile.rhel9 +++ /dev/null @@ -1,95 +0,0 @@ -# This image provides a Python 3.11 environment you can use to run your Python -# applications. -FROM ubi9/s2i-base:1 - -EXPOSE 8080 - -ENV PYTHON_VERSION=3.11 \ - PATH=$HOME/.local/bin/:$PATH \ - PYTHONUNBUFFERED=1 \ - PYTHONIOENCODING=UTF-8 \ - LC_ALL=en_US.UTF-8 \ - LANG=en_US.UTF-8 \ - CNB_STACK_ID=com.redhat.stacks.ubi9-python-311 \ - CNB_USER_ID=1001 \ - CNB_GROUP_ID=0 \ - PIP_NO_CACHE_DIR=off - -ENV SUMMARY="Platform for building and running Python $PYTHON_VERSION applications" \ - DESCRIPTION="Python $PYTHON_VERSION available as container is a base platform for \ -building and running various Python $PYTHON_VERSION applications and frameworks. \ -Python is an easy to learn, powerful programming language. It has efficient high-level \ -data structures and a simple but effective approach to object-oriented programming. \ -Python's elegant syntax and dynamic typing, together with its interpreted nature, \ -make it an ideal language for scripting and rapid application development in many areas \ -on most platforms." - -LABEL summary="$SUMMARY" \ - description="$DESCRIPTION" \ - io.k8s.description="$DESCRIPTION" \ - io.k8s.display-name="Python 3.11" \ - io.openshift.expose-services="8080:http" \ - io.openshift.tags="builder,python,python311,python-311,rh-python311" \ - com.redhat.component="python-311-container" \ - name="ubi9/python-311" \ - usage="s2i build https://github.com/sclorg/s2i-python-container.git --context-dir=3.11/test/setup-test-app/ ubi9/python-311 python-sample-app" \ - com.redhat.license_terms="https://www.redhat.com/en/about/red-hat-end-user-license-agreements#UBI" \ - io.buildpacks.stack.id="com.redhat.stacks.ubi9-python-311" \ - maintainer="SoftwareCollections.org " - -RUN INSTALL_PKGS="python3.11 python3.11-devel python3.11-pip nss_wrapper-libs httpd \ - httpd-devel mod_ssl mod_auth_gssapi mod_ldap mod_session \ - atlas-devel gcc-gfortran libffi-devel libtool-ltdl enchant \ - krb5-devel" && \ - yum -y --setopt=tsflags=nodocs install $INSTALL_PKGS && \ - rpm -V $INSTALL_PKGS && \ - # Remove redhat-logos-httpd (httpd dependency) to keep image size smaller. - rpm -e --nodeps redhat-logos-httpd && \ - yum -y clean all --enablerepo='*' - -# Copy the S2I scripts from the specific language image to $STI_SCRIPTS_PATH. -COPY 3.11/s2i/bin/ $STI_SCRIPTS_PATH - -# Copy extra files to the image. -COPY 3.11/root/ / - -# Python 3.7+ only -# Yes, the directory below is already copied by the previous command. -# The problem here is that the wheels directory is copied as a symlink. -# Only if you specify symlink directly as a source, COPY copies all the -# files from the symlink destination. -COPY 3.11/root/opt/wheels /opt/wheels -# - Create a Python virtual environment for use by any application to avoid -# potential conflicts with Python packages preinstalled in the main Python -# installation. -# - In order to drop the root user, we have to make some directories world -# writable as OpenShift default security model is to run the container -# under random UID. -RUN \ - python3.11 -m venv ${APP_ROOT} && \ - # Python 3.7+ only code, Python <3.7 installs pip from PyPI in the assemble script. \ - # We have to upgrade pip to a newer verison because \ - # pip < 19.3 does not support manylinux2014 wheels. Only manylinux2014 (and later) wheels \ - # support platforms like ppc64le, aarch64 or armv7 \ - # We are newly using wheel from one of the latest stable Fedora releases (from RPM python-pip-wheel) \ - # because it's tested better then whatever version from PyPI and contains useful patches. \ - # We have to do it here (in the macro) so the permissions are correctly fixed and pip is able \ - # to reinstall itself in the next build phases in the assemble script if user wants the latest version \ - ${APP_ROOT}/bin/pip install /opt/wheels/pip-* && \ - rm -r /opt/wheels && \ - chown -R 1001:0 ${APP_ROOT} && \ - fix-permissions ${APP_ROOT} -P && \ - rpm-file-permissions && \ - # The following echo adds the unset command for the variables set below to the \ - # venv activation script. This prevents the virtual environment from being \ - # activated multiple times and also every time the prompt is rendered. \ - echo "unset BASH_ENV PROMPT_COMMAND ENV" >> ${APP_ROOT}/bin/activate -# Ensure the virtualenv is activated in interactive shells -ENV BASH_ENV="${APP_ROOT}/bin/activate" \ - ENV="${APP_ROOT}/bin/activate" \ - PROMPT_COMMAND=". ${APP_ROOT}/bin/activate" - -USER 1001 - -# Set the default CMD to print the usage of the language image. -CMD $STI_SCRIPTS_PATH/usage diff --git a/3.11/README.md b/3.11/README.md deleted file mode 100644 index 2a93f5e0..00000000 --- a/3.11/README.md +++ /dev/null @@ -1,386 +0,0 @@ -Python 3.11 container image -========================= - -This container image includes Python 3.11 as a [S2I](https://github.com/openshift/source-to-image) base image for your Python 3.11 applications. -Users can choose between RHEL, CentOS Stream, and Fedora based builder images. -The RHEL images are available in the [Red Hat Container Catalog](https://catalog.redhat.com/software/containers/explore), -CentOS Stream images are available on [Quay.io](https://quay.io/organization/sclorg), -and the Fedora images are available on [Quay.io](https://quay.io/organization/fedora). -The resulting image can be run using [podman](https://github.com/containers/libpod) or -[docker](http://docker.io). - -Note: while the examples in this README are calling `podman`, you can replace any such calls by `docker` with the same arguments - -Description ------------ - -Python 3.11 available as container is a base platform for -building and running various Python 3.11 applications and frameworks. -Python is an easy to learn, powerful programming language. It has efficient high-level -data structures and a simple but effective approach to object-oriented programming. -Python's elegant syntax and dynamic typing, together with its interpreted nature, -make it an ideal language for scripting and rapid application development in many areas -on most platforms. - -This container image includes an npm utility -(see [base image repository](https://github.com/sclorg/s2i-base-container/tree/master/base)), -so users can use it to install JavaScript -modules for their web applications. There is no guarantee for any specific npm or nodejs -version, that is included in the image; those versions can be changed anytime and -the nodejs itself is included just to make the npm work. - -Usage in Openshift ------------------- - -For this, we will assume that you are using one of the supported images available via imagestream tags in Openshift, eg. `python:3.11-ubi9` -Building a simple [python-sample-app](https://github.com/sclorg/django-ex.git) application -in Openshift can be achieved with the following step: - - ``` - oc new-app python:3.11-ubi9~https://github.com/sclorg/django-ex.git - ``` - -**Accessing the application:** -``` -$ oc get pods -$ oc exec -- curl 127.0.0.1:8080 -``` - -Source-to-Image framework and scripts -------------------------------------- -This image supports the [Source-to-Image](https://docs.openshift.com/container-platform/4.14/openshift_images/create-images.html#images-create-s2i_create-images) -(S2I) strategy in OpenShift. The Source-to-Image is an OpenShift framework -which makes it easy to write images that take application source code as -an input, use a builder image like this Python container image, and produce -a new image that runs the assembled application as an output. - -To support the Source-to-Image framework, important scripts are included in the builder image: - -* The `/usr/libexec/s2i/assemble` script inside the image is run to produce a new image with the application artifacts. -The script takes sources of a given application and places them into appropriate directories inside the image. -It utilizes some common patterns in Perl application development (see the **Environment variables** section below). -* The `/usr/libexec/s2i/run` script is set as the default command in the resulting container image (the new image with the application artifacts). -It runs your application according to settings in `APP_MODULE`, `APP_FILE` or `APP_SCRIPT` environment variables or it tries to detect the best -way automatically. - -Building an application using a Dockerfile ------------------------------------------- -Compared to the Source-to-Image strategy, using a Dockerfile is a more -flexible way to build a Python container image with an application. -Use a Dockerfile when Source-to-Image is not sufficiently flexible for you or -when you build the image outside of the OpenShift environment. - -To use the Python image in a Dockerfile, follow these steps: -#### 1. Pull a base builder image to build on - -``` -podman pull registry.access.redhat.com/ubi9/python-311 -``` - -#### 2. Pull and application code - -An example application available at https://github.com/sclorg/django-ex.git is used here. Feel free to clone the repository for further experiments. -You can also take a look at code examples in s2i-python-container repository: https://github.com/sclorg/s2i-python-container/tree/master/examples - -``` -git clone https://github.com/sclorg/django-ex.git app-src -``` - -#### 3. Prepare an application inside a container - -This step usually consists of at least these parts: - -* putting the application source into the container -* installing the dependencies -* setting the default command in the resulting image - -For all these three parts, users can either setup all manually and use commands `python` and `pip` explicitly in the Dockerfile, -or users can use the Source-to-Image scripts inside the image. - -The manual way comes with the highest level of flexibility but requires you to know how to work -with modules or software collections manually, how to setup virtual environment with the right version -of Python and many more. On the other hand, using Source-to-Image scripts makes your Dockerfile -prepared for a future flawless switch to a newer or different platform. - -To use the Source-to-Image scripts and build an image using a Dockerfile, create a Dockerfile with this content: - -``` -FROM registry.access.redhat.com/ubi9/python-311 - -# Add application sources to a directory that the assemble script expects them -# and set permissions so that the container runs without root access -USER 0 -ADD app-src /tmp/src -RUN /usr/bin/fix-permissions /tmp/src -USER 1001 - -# Install the dependencies -RUN /usr/libexec/s2i/assemble - -# Set the default command for the resulting image -CMD /usr/libexec/s2i/run -``` - -If you decide not to use the Source-to-Image scripts, you will need to manually tailor the Dockerfile to your application and its needs. -Example Dockerfile for a simple Django application: - -``` -FROM registry.access.redhat.com/ubi9/python-311 - -# Add application sources with correct permissions for OpenShift -USER 0 -ADD app-src . -RUN chown -R 1001:0 ./ -USER 1001 - -# Install the dependencies -RUN pip install -U "pip>=19.3.1" && \ - pip install -r requirements.txt && \ - python manage.py collectstatic --noinput && \ - python manage.py migrate - -# Run the application -CMD python manage.py runserver 0.0.0.0:8080 -``` - -#### 4. Build a new image from a Dockerfile prepared in the previous step - -``` -podman build -t python-app . -``` - -#### 5. Run the resulting image with final application - -``` -podman run -d python-app -``` - -Environment variables ---------------------- - -To set these environment variables, you can place them as a key value pair into a `.s2i/environment` -file inside your source code repository. - -* **APP_SCRIPT** - - Used to run the application from a script file. - This should be a path to a script file (defaults to `app.sh` unless set to null) that will be - run to start the application. - -* **APP_FILE** - - Used to run the application from a Python script. - This should be a path to a Python file (defaults to `app.py` unless set to null) that will be - passed to the Python interpreter to start the application. - -* **APP_MODULE** - - Used to run the application with Gunicorn, as documented - [here](http://docs.gunicorn.org/en/latest/run.html#gunicorn). - This variable specifies a WSGI callable with the pattern - `MODULE_NAME:VARIABLE_NAME`, where `MODULE_NAME` is the full dotted path - of a module, and `VARIABLE_NAME` refers to a WSGI callable inside the - specified module. - Gunicorn will look for a WSGI callable named `application` if not specified. - - If `APP_MODULE` is not provided, the `run` script will look for a `wsgi.py` - file in your project and use it if it exists. - - If using `setup.py` for installing the application, the `MODULE_NAME` part - can be read from there. For an example, see - [setup-test-app](https://github.com/sclorg/s2i-python-container/tree/master/3.11/test/setup-test-app). - -* **APP_HOME** - - This variable can be used to specify a sub-directory in which the application to be run is contained. - The directory pointed to by this variable needs to contain `wsgi.py` (for Gunicorn) or `manage.py` (for Django). - - If `APP_HOME` is not provided, the `assemble` and `run` scripts will use the application's root - directory. - -* **APP_CONFIG** - - Path to a valid Python file with a - [Gunicorn configuration](http://docs.gunicorn.org/en/latest/configure.html#configuration-file) file. - -* **DISABLE_MIGRATE** - - Set this variable to a non-empty value to inhibit the execution of 'manage.py migrate' - when the produced image is run. This only affects Django projects. See - "Handling Database Migrations" section of [Django blogpost on OpenShift blog]( - https://blog.openshift.com/migrating-django-applications-openshift-3/) on suggestions - how/when to run DB migrations in OpenShift environment. Most importantly, - note that running DB migrations from two or more pods might corrupt your database. - -* **DISABLE_COLLECTSTATIC** - - Set this variable to a non-empty value to inhibit the execution of - 'manage.py collectstatic' during the build. This only affects Django projects. - -* **DISABLE_SETUP_PY_PROCESSING** / **DISABLE_PYPROJECT_TOML_PROCESSING** - - Set this to a non-empty value to skip processing of setup.{py,cfg} or pyproject.toml script if you - use `-e .` in requirements.txt to trigger its processing or you don't want - your application to be installed into site-packages directory. - -* **ENABLE_PIPENV** - - Set this variable to use [Pipenv](https://github.com/pypa/pipenv), - the higher-level Python packaging tool, to manage dependencies of the application. - This should be used only if your project contains properly formated Pipfile - and Pipfile.lock. - -* **PIN_PIPENV_VERSION** - - Set this variable together with `ENABLE_PIPENV` to use a specific version of Pipenv. - If not set, the latest stable version from PyPI is installed. - For example `PIN_PIPENV_VERSION=2018.11.26` installs `pipenv==2018.11.26`. - -* **ENABLE_MICROPIPENV** - - Set this variable to use [micropipenv](https://github.com/thoth-station/micropipenv), - a lightweight wrapper for pip to support requirements.txt, Pipenv and Poetry lock - files or converting them to pip-tools compatible output. Designed for containerized Python applications. - Available only for Python 3 images. - -* **ENABLE_INIT_WRAPPER** - - Set this variable to a non-empty value to make use of an init wrapper. - This is useful for servers that are not capable of reaping zombie - processes, such as Django development server or Tornado. This option can - be used together with **APP_SCRIPT** or **APP_FILE**. It never applies - to Gunicorn used through **APP_MODULE** as Gunicorn reaps zombie - processes correctly. - -* **PIP_INDEX_URL** - - Set this variable to use a custom index URL or mirror to download required - packages during build process. This affects packages listed in - requirements.txt. It also affects the installation of pipenv and - micropipenv and the update of pip in the container, though if not found in - the custom index, the container will try to install/update them from - upstream PyPI afterwards. - -* **PORT** - - HTTP(S) port your application should listen on. The default is 8080. - `PORT` is used only for Django development server and for Gunicorn - with the default configutation (no `APP_CONFIG` or `GUNICORN_CMD_ARGS` specified). - -* **UPGRADE_PIP_TO_LATEST** - - Set this variable to a non-empty value to have the 'pip' program and related - python packages (setuptools and wheel) be upgraded to the most recent version - before any Python packages are installed. If not set, the container will use - the stable pip version this container was built with, taken from a recent Fedora release. - -* **WEB_CONCURRENCY** - - Set this to change the default setting for the number of - [workers](http://docs.gunicorn.org/en/stable/settings.html#workers). By - default, this is set to the number of available cores times 2, capped - at 12. - - -Source repository layout ------------------------- - -You do not need to change anything in your existing Python project's repository. -However, if these files exist they will affect the behavior of the build process: - -* **requirements.txt** - - List of dependencies to be installed with `pip`. The format is documented - [here](https://pip.pypa.io/en/latest/user_guide.html#requirements-files). - - -* **Pipfile** - - The replacement for requirements.txt, project is currently under active - design and development, as documented [here](https://github.com/pypa/pipfile). - Set `ENABLE_PIPENV` environment variable to true in order to process this file. - - -* **setup.py** - - Configures various aspects of the project, including installation of - dependencies, as documented - [here](https://packaging.python.org/guides/distributing-packages-using-setuptools/?highlight=distributing#setup-py). - For most projects, it is sufficient to simply use `requirements.txt` or - `Pipfile`. Set `DISABLE_SETUP_PY_PROCESSING` environment variable to true - in order to skip processing of this file. - -Run strategies --------------- - -The container image produced by s2i-python executes your project in one of the -following ways, in precedence order: - -* **Gunicorn** - - The Gunicorn WSGI HTTP server is used to serve your application in the case that it - is installed. It can be installed by listing it either in the `requirements.txt` - file or in the `install_requires` section of the `setup.py` file. - - If a file named `wsgi.py` is present in your repository, it will be used as - the entry point to your application. This can be overridden with the - environment variable `APP_MODULE`. - This file is present in Django projects by default. - - If you have both Django and Gunicorn in your requirements, your Django project - will automatically be served using Gunicorn. - - The default setting for Gunicorn (`--bind=0.0.0.0:$PORT --access-logfile=-`) is applied - only if both `$APP_CONFIG` and `$GUNICORN_CMD_ARGS` are not defined. - -* **Django development server** - - If you have Django in your requirements but don't have Gunicorn, then your - application will be served using Django's development web server. However, this is not - recommended for production environments. - -* **Python script** - - This would be used where you provide a Python code file for running you - application. It will be used in the case where you specify a path to a - Python script via the `APP_FILE` environment variable, defaulting to a - file named `app.py` if it exists. The script is passed to a regular - Python interpreter to launch your application. - -* **Application script file** - - This is the most general way of executing your application. It will be - used in the case where you specify a path to an executable script file - via the `APP_SCRIPT` environment variable, defaulting to a file named - `app.sh` if it exists. The script is executed directly to launch your - application. - -Hot deploy ----------- - -If you are using Django, hot deploy will work out of the box. - -To enable hot deploy while using Gunicorn, make sure you have a Gunicorn -configuration file inside your repository with the -[`reload`](https://gunicorn-docs.readthedocs.org/en/latest/settings.html#reload) -option set to `true`. Make sure to specify your config via the `APP_CONFIG` -environment variable. - -To change your source code in running container, use podman's (or docker's) -[exec](https://github.com/containers/podman/blob/main/docs/source/markdown/podman-exec.1.md) command: - -``` -podman exec -it /bin/bash -``` - -After you enter into the running container, your current directory is set -to `/opt/app-root/src`, where the source code is located. - - -See also --------- -Dockerfile and other sources are available on https://github.com/sclorg/s2i-python-container. -In that repository you also can find another versions of Python environment Dockerfiles. -Dockerfile for RHEL8 is called `Dockerfile.rhel8`, for RHEL9 it's `Dockerfile.rhel9`, -for CentOS Stream 9 it's `Dockerfile.c9s`, for CentOS Stream 10 it's `Dockerfile.c10s`, -and the Fedora Dockerfile is called `Dockerfile.fedora`. diff --git a/3.11/root/opt/app-root/etc/generate_container_user b/3.11/root/opt/app-root/etc/generate_container_user deleted file mode 100644 index a7fd74d6..00000000 --- a/3.11/root/opt/app-root/etc/generate_container_user +++ /dev/null @@ -1,19 +0,0 @@ -# Set current user in nss_wrapper -USER_ID=$(id -u) -GROUP_ID=$(id -g) - -if [ x"$USER_ID" != x"0" -a x"$USER_ID" != x"1001" ]; then - - NSS_WRAPPER_PASSWD=/opt/app-root/etc/passwd - NSS_WRAPPER_GROUP=/etc/group - - cat /etc/passwd | sed -e 's/^default:/builder:/' > $NSS_WRAPPER_PASSWD - - echo "default:x:${USER_ID}:${GROUP_ID}:Default Application User:${HOME}:/bin/bash" >> $NSS_WRAPPER_PASSWD - - export NSS_WRAPPER_PASSWD - export NSS_WRAPPER_GROUP - - LD_PRELOAD=libnss_wrapper.so - export LD_PRELOAD -fi diff --git a/3.11/root/opt/wheels b/3.11/root/opt/wheels deleted file mode 120000 index 4eabc067..00000000 --- a/3.11/root/opt/wheels +++ /dev/null @@ -1 +0,0 @@ -../../../src/root/opt/wheels/ \ No newline at end of file diff --git a/3.11/s2i/bin/assemble b/3.11/s2i/bin/assemble deleted file mode 100755 index 15d2fbbd..00000000 --- a/3.11/s2i/bin/assemble +++ /dev/null @@ -1,134 +0,0 @@ -#!/bin/bash - -function is_django_installed() { - python -c "import django" &>/dev/null -} - -function should_collectstatic() { - is_django_installed && [[ -z "$DISABLE_COLLECTSTATIC" ]] -} - -function virtualenv_bin() { - # New versions of Python (>3.6) should use venv module - # from stdlib instead of virtualenv package - python3.11 -m venv $1 -} - -# Install pipenv or micropipenv to the separate virtualenv to isolate it -# from system Python packages and packages in the main -# virtualenv. Executable is simlinked into ~/.local/bin -# to be accessible. This approach is inspired by pipsi -# (pip script installer). -function install_tool() { - echo "---> Installing $1 packaging tool ..." - VENV_DIR=$HOME/.local/venvs/$1 - virtualenv_bin "$VENV_DIR" - # First, try to install the tool without --isolated which means that if you - # have your own PyPI mirror, it will take it from there. If this try fails, try it - # again with --isolated which ignores external pip settings (env vars, config file) - # and installs the tool from PyPI (needs internet connetion). - # $1$2 combines package name with [extras] or version specifier if is defined as $2``` - if ! $VENV_DIR/bin/pip install -U $1$2; then - echo "WARNING: Installation of $1 failed, trying again from official PyPI with pip --isolated install" - $VENV_DIR/bin/pip install --isolated -U $1$2 # Combines package name with [extras] or version specifier if is defined as $2``` - fi - mkdir -p $HOME/.local/bin - ln -s $VENV_DIR/bin/$1 $HOME/.local/bin/$1 -} - -set -e - -# First of all, check that we don't have disallowed combination of ENVs -if [[ ! -z "$ENABLE_PIPENV" && ! -z "$ENABLE_MICROPIPENV" ]]; then - echo "ERROR: Pipenv and micropipenv cannot be enabled at the same time!" - # podman/buildah does not relay this exit code but it will be fixed hopefuly - # https://github.com/containers/buildah/issues/2305 - exit 3 -fi - -shopt -s dotglob -echo "---> Installing application source ..." -mv /tmp/src/* "$HOME" - -# set permissions for any installed artifacts -fix-permissions /opt/app-root -P - - -if [[ ! -z "$PIP_INDEX_URL" ]]; then - echo "---> Creating pip.ini config file" - echo "[global] -index-url = $PIP_INDEX_URL" >> /opt/app-root/src/pip.ini -fi - -if [[ ! -z "$UPGRADE_PIP_TO_LATEST" ]]; then - echo "---> Upgrading pip, setuptools and wheel to latest version ..." - if ! pip install -U pip setuptools wheel; then - echo "WARNING: Installation of the latest pip, setuptools and wheel failed, trying again from official PyPI with pip --isolated install" - pip install --isolated -U pip setuptools wheel - fi -fi - -if [[ ! -z "$ENABLE_PIPENV" ]]; then - if [[ ! -z "$PIN_PIPENV_VERSION" ]]; then - # Add == as a prefix to pipenv version, if defined - PIN_PIPENV_VERSION="==$PIN_PIPENV_VERSION" - fi - install_tool "pipenv" "$PIN_PIPENV_VERSION" - echo "---> Installing dependencies via pipenv ..." - if [[ -f Pipfile ]]; then - pipenv install --deploy - elif [[ -f requirements.txt ]]; then - pipenv install -r requirements.txt - fi - # pipenv check -elif [[ ! -z "$ENABLE_MICROPIPENV" ]]; then - install_tool "micropipenv" "[toml]" - echo "---> Installing dependencies via micropipenv ..." - # micropipenv detects Pipfile.lock and requirements.txt in this order - micropipenv install --deploy -elif [[ -f requirements.txt ]]; then - echo "---> Installing dependencies ..." - pip install -r requirements.txt -fi - -if [[ ( -f setup.py || -f setup.cfg ) && -z "$DISABLE_SETUP_PY_PROCESSING" ]]; then - echo "---> Installing application (via setup.{py,cfg})..." - pip install . -fi - -if [[ -f pyproject.toml && -z "$DISABLE_PYPROJECT_TOML_PROCESSING" ]]; then - echo "---> Installing application (via pyproject.toml)..." - pip install . -fi - -if should_collectstatic; then - ( - echo "---> Collecting Django static files ..." - - APP_HOME=$(readlink -f "${APP_HOME:-.}") - # Change the working directory to APP_HOME - PYTHONPATH="$(pwd)${PYTHONPATH:+:$PYTHONPATH}" - cd "$APP_HOME" - - # Look for 'manage.py' in the current directory - manage_file=./manage.py - - if [[ ! -f "$manage_file" ]]; then - echo "WARNING: seems that you're using Django, but we could not find a 'manage.py' file." - echo "'manage.py collectstatic' ignored." - exit - fi - - if ! python $manage_file collectstatic --dry-run --noinput &> /dev/null; then - echo "WARNING: could not run 'manage.py collectstatic'. To debug, run:" - echo " $ python $manage_file collectstatic --noinput" - echo "Ignore this warning if you're not serving static files with Django." - exit - fi - - python $manage_file collectstatic --noinput - ) -fi - -# set permissions for any installed artifacts -fix-permissions /opt/app-root -P diff --git a/3.11/s2i/bin/init-wrapper b/3.11/s2i/bin/init-wrapper deleted file mode 100755 index 26c8767d..00000000 --- a/3.11/s2i/bin/init-wrapper +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -# Overview of how this script works: http://veithen.io/2014/11/16/sigterm-propagation.html -# Set a trap to kill the main app process when this -# init script receives SIGTERM or SIGINT -trap 'kill -s TERM $PID' TERM INT -# Execute the main application in the background -"$@" & -PID=$! -# wait command always terminates when trap is caught, even if the process hasn't finished yet -wait $PID -# Remove the trap and wait till the app process finishes completely -trap - TERM INT -# We wait again, since the first wait terminates when trap is caught -wait $PID -# Exit with the exit code of the app process -STATUS=$? -exit $STATUS diff --git a/3.11/s2i/bin/run b/3.11/s2i/bin/run deleted file mode 100755 index 7003f038..00000000 --- a/3.11/s2i/bin/run +++ /dev/null @@ -1,155 +0,0 @@ -#!/bin/bash -source /opt/app-root/etc/generate_container_user - -set -e - -function is_gunicorn_installed() { - hash gunicorn &>/dev/null -} - -function is_django_installed() { - python -c "import django" &>/dev/null -} - -function should_migrate() { - is_django_installed && [[ -z "$DISABLE_MIGRATE" ]] -} - -# Guess the number of workers according to the number of cores -function get_default_web_concurrency() { - limit_vars=$(cgroup-limits) - local $limit_vars - if [ -z "${NUMBER_OF_CORES:-}" ]; then - echo 1 - return - fi - - local max=$((NUMBER_OF_CORES*2)) - # Require at least 43 MiB and additional 40 MiB for every worker - local default=$(((${MEMORY_LIMIT_IN_BYTES:-MAX_MEMORY_LIMIT_IN_BYTES}/1024/1024 - 43) / 40)) - default=$((default > max ? max : default)) - default=$((default < 1 ? 1 : default)) - # According to http://docs.gunicorn.org/en/stable/design.html#how-many-workers, - # 12 workers should be enough to handle hundreds or thousands requests per second - default=$((default > 12 ? 12 : default)) - echo $default -} - -function maybe_run_in_init_wrapper() { - if [[ -z "$ENABLE_INIT_WRAPPER" ]]; then - exec "$@" - else - exec $STI_SCRIPTS_PATH/init-wrapper "$@" - fi -} - -# Look for gunicorn>=20.1.0 to utilize gunicorn.conf.py -if is_gunicorn_installed && [[ -f "gunicorn.conf.py" ]]; then - ret=$(python -c 'import gunicorn -ver = gunicorn.version_info -print(0 if ver[0]>=21 or (ver[0] == 20 and ver[1] >= 1) else 1)') - grep -q "wsgi_app" gunicorn.conf.py && grep_result=0 || grep_result=1 - if [[ $ret -eq 0 ]] && [[ $grep_result -eq 0 ]]; then - echo "---> Using gunicorn.conf.py" - echo "---> Serving application with gunicorn ..." - exec gunicorn - fi -fi - -APP_HOME=$(readlink -f "${APP_HOME:-.}") -# Change the working directory to APP_HOME -PYTHONPATH="$(pwd)${PYTHONPATH:+:$PYTHONPATH}" -cd "$APP_HOME" - -if [ -z "$APP_SCRIPT" ] && [ -z "$APP_FILE" ] && [ -z "$APP_MODULE" ]; then - # Set default values for APP_SCRIPT and APP_FILE only when all three APP_ - # variables are not defined by user. This prevents a situation when - # APP_MODULE is defined to app:application but the app.py file is found as the - # APP_FILE and then executed by Python instead of gunicorn. - APP_SCRIPT="app.sh" - APP_SCRIPT_DEFAULT=1 - APP_FILE="app.py" - APP_FILE_DEFAULT=1 -fi - -if [ ! -z "$APP_SCRIPT" ]; then - if [[ -f "$APP_SCRIPT" ]]; then - echo "---> Running application from script ($APP_SCRIPT) ..." - if [[ "$APP_SCRIPT" != /* ]]; then - APP_SCRIPT="./$APP_SCRIPT" - fi - maybe_run_in_init_wrapper "$APP_SCRIPT" - elif [[ -z "$APP_SCRIPT_DEFAULT" ]]; then - echo "ERROR: file '$APP_SCRIPT' not found." && exit 1 - fi -fi - -if [ ! -z "$APP_FILE" ]; then - if [[ -f "$APP_FILE" ]]; then - echo "---> Running application from Python script ($APP_FILE) ..." - maybe_run_in_init_wrapper python "$APP_FILE" - elif [[ -z "$APP_FILE_DEFAULT" ]]; then - echo "ERROR: file '$APP_FILE' not found." && exit 1 - fi -fi - -# Look for 'manage.py' in the current directory -manage_file=./manage.py - -if should_migrate; then - if [[ -f "$manage_file" ]]; then - echo "---> Migrating database ..." - python "$manage_file" migrate --noinput - else - echo "WARNING: seems that you're using Django, but we could not find a 'manage.py' file." - echo "Skipped 'python manage.py migrate'." - fi -fi - -# If not set, use 8080 as the default port -if [ -z "$PORT" ]; then - PORT=8080 -fi - -if is_gunicorn_installed; then - setup_py=$(find "$HOME" -maxdepth 2 -type f -name 'setup.py' -print -quit) - # Look for wsgi module in the current directory - if [[ -z "$APP_MODULE" && -f "./wsgi.py" ]]; then - APP_MODULE=wsgi - elif [[ -z "$APP_MODULE" && -f "$setup_py" ]]; then - APP_MODULE="$(python "$setup_py" --name)" - fi - - if [[ "$APP_MODULE" ]]; then - export WEB_CONCURRENCY=${WEB_CONCURRENCY:-$(get_default_web_concurrency)} - - # Default settings for gunicorn if none of the custom are set - if [ -z "$APP_CONFIG" ] && [ -z "$GUNICORN_CMD_ARGS" ]; then - GUNICORN_CMD_ARGS="--bind=0.0.0.0:$PORT --access-logfile=-" - gunicorn_settings_source="default" - else - gunicorn_settings_source="custom" - fi - - # Gunicorn can read GUNICORN_CMD_ARGS as an env variable; we also pass them as - # arguments explicitly for compatibility with older Gunicorn versions. - echo "---> Serving application with gunicorn ($APP_MODULE) with $gunicorn_settings_source settings ..." - exec gunicorn "$APP_MODULE" $GUNICORN_CMD_ARGS --config "$APP_CONFIG" - fi -fi - -if is_django_installed; then - if [[ -f "$manage_file" ]]; then - echo "---> Serving application with 'manage.py runserver 0.0.0.0:$PORT' ..." - echo "WARNING: this is NOT a recommended way to run you application in production!" - echo "Consider using gunicorn or some other production web server." - maybe_run_in_init_wrapper python "$manage_file" runserver 0.0.0.0:$PORT - else - echo "WARNING: seems that you're using Django, but we could not find a 'manage.py' file." - echo "Skipped 'python manage.py runserver'." - fi -fi - ->&2 echo "ERROR: don't know how to run your application." ->&2 echo "Please set either APP_MODULE, APP_FILE or APP_SCRIPT environment variables, or create a file 'app.py' to launch your application." -exit 1 diff --git a/3.11/s2i/bin/usage b/3.11/s2i/bin/usage deleted file mode 100755 index ae9c8555..00000000 --- a/3.11/s2i/bin/usage +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -DISTRO=`cat /etc/*-release | grep ^ID= | grep -Po '".*?"' | tr -d '"'` -NAMESPACE=centos -[[ $DISTRO =~ rhel* ]] && NAMESPACE=rhscl - -cat < -- curl 127.0.0.1:8080 -EOF diff --git a/3.11/test/__init__.py b/3.11/test/__init__.py deleted file mode 120000 index d0f4746a..00000000 --- a/3.11/test/__init__.py +++ /dev/null @@ -1 +0,0 @@ -../../test/__init__.py \ No newline at end of file diff --git a/3.11/test/app-home-test-app b/3.11/test/app-home-test-app deleted file mode 120000 index f6b42e77..00000000 --- a/3.11/test/app-home-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/app-home-test-app \ No newline at end of file diff --git a/3.11/test/app-module-test-app b/3.11/test/app-module-test-app deleted file mode 120000 index fa20034b..00000000 --- a/3.11/test/app-module-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/app-module-test-app \ No newline at end of file diff --git a/3.11/test/check_imagestreams.py b/3.11/test/check_imagestreams.py deleted file mode 120000 index 56bb2be7..00000000 --- a/3.11/test/check_imagestreams.py +++ /dev/null @@ -1 +0,0 @@ -../../common/check_imagestreams.py \ No newline at end of file diff --git a/3.11/test/conftest.py b/3.11/test/conftest.py deleted file mode 120000 index 3f2d7840..00000000 --- a/3.11/test/conftest.py +++ /dev/null @@ -1 +0,0 @@ -../../test/conftest.py \ No newline at end of file diff --git a/3.11/test/django-different-port-test-app b/3.11/test/django-different-port-test-app deleted file mode 120000 index cc115af1..00000000 --- a/3.11/test/django-different-port-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/django-different-port-test-app \ No newline at end of file diff --git a/3.11/test/django-test-app b/3.11/test/django-test-app deleted file mode 120000 index 52cebf3b..00000000 --- a/3.11/test/django-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/django-test-app \ No newline at end of file diff --git a/3.11/test/from-dockerfile/Dockerfile.tpl b/3.11/test/from-dockerfile/Dockerfile.tpl deleted file mode 120000 index ba88ccc4..00000000 --- a/3.11/test/from-dockerfile/Dockerfile.tpl +++ /dev/null @@ -1 +0,0 @@ -../../../src/test/from-dockerfile/Dockerfile.tpl \ No newline at end of file diff --git a/3.11/test/from-dockerfile/Dockerfile_no_s2i.tpl b/3.11/test/from-dockerfile/Dockerfile_no_s2i.tpl deleted file mode 100644 index da2f43ff..00000000 --- a/3.11/test/from-dockerfile/Dockerfile_no_s2i.tpl +++ /dev/null @@ -1,16 +0,0 @@ -FROM #IMAGE_NAME# # Replaced by sed in ct_test_app_dockerfile - -# Add application sources with correct permissions for OpenShift -USER 0 -ADD app-src . -RUN chown -R 1001:0 ./ -USER 1001 - -# Install the dependencies -RUN pip install -U "pip>=19.3.1" && \ - pip install -r requirements.txt && \ - python manage.py collectstatic --noinput && \ - python manage.py migrate - -# Run the application -CMD python manage.py runserver 0.0.0.0:8080 diff --git a/3.11/test/gunicorn-config-different-port-test-app b/3.11/test/gunicorn-config-different-port-test-app deleted file mode 120000 index c8eb6171..00000000 --- a/3.11/test/gunicorn-config-different-port-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/gunicorn-config-different-port-test-app \ No newline at end of file diff --git a/3.11/test/gunicorn-different-port-test-app b/3.11/test/gunicorn-different-port-test-app deleted file mode 120000 index 72c8e433..00000000 --- a/3.11/test/gunicorn-different-port-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/gunicorn-different-port-test-app \ No newline at end of file diff --git a/3.11/test/gunicorn-python-configfile-different-port-test-app b/3.11/test/gunicorn-python-configfile-different-port-test-app deleted file mode 120000 index 9139ee17..00000000 --- a/3.11/test/gunicorn-python-configfile-different-port-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/gunicorn-python-configfile-different-port-test-app \ No newline at end of file diff --git a/3.11/test/imagestreams b/3.11/test/imagestreams deleted file mode 120000 index 7a0aee9c..00000000 --- a/3.11/test/imagestreams +++ /dev/null @@ -1 +0,0 @@ -../../imagestreams \ No newline at end of file diff --git a/3.11/test/locale-test-app b/3.11/test/locale-test-app deleted file mode 120000 index 9105ec08..00000000 --- a/3.11/test/locale-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/locale-test-app \ No newline at end of file diff --git a/3.11/test/micropipenv-requirements-test-app b/3.11/test/micropipenv-requirements-test-app deleted file mode 120000 index cb2ddcf0..00000000 --- a/3.11/test/micropipenv-requirements-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/micropipenv-requirements-test-app \ No newline at end of file diff --git a/3.11/test/micropipenv-test-app/.gitignore b/3.11/test/micropipenv-test-app/.gitignore deleted file mode 100644 index ba746605..00000000 --- a/3.11/test/micropipenv-test-app/.gitignore +++ /dev/null @@ -1,57 +0,0 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] - -# C extensions -*.so - -# Distribution / packaging -.Python -env/ -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -*.egg-info/ -.installed.cfg -*.egg - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*,cover - -# Translations -*.mo -*.pot - -# Django stuff: -*.log - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ diff --git a/3.11/test/micropipenv-test-app/.s2i/environment b/3.11/test/micropipenv-test-app/.s2i/environment deleted file mode 100644 index 29efed4a..00000000 --- a/3.11/test/micropipenv-test-app/.s2i/environment +++ /dev/null @@ -1,5 +0,0 @@ -ENABLE_MICROPIPENV=true -DISABLE_SETUP_PY_PROCESSING=true -# This tests second try to install micropipenv with --isolated -# because the first one won't work with following setting -PIP_INDEX_URL=https://example.com/ diff --git a/3.11/test/micropipenv-test-app/Pipfile b/3.11/test/micropipenv-test-app/Pipfile deleted file mode 100644 index 9944bb52..00000000 --- a/3.11/test/micropipenv-test-app/Pipfile +++ /dev/null @@ -1,14 +0,0 @@ -[[source]] -url = "https://pypi.python.org/simple" -verify_ssl = true -name = "pypi" - -[packages] -"e1839a8" = {path = ".", editable = true} -requests = "==2.20.0" - -[dev-packages] -pytest = ">=2.8.0" - -[requires] -python_version = "3.11" diff --git a/3.11/test/micropipenv-test-app/Pipfile.lock b/3.11/test/micropipenv-test-app/Pipfile.lock deleted file mode 100644 index 7fc7c766..00000000 --- a/3.11/test/micropipenv-test-app/Pipfile.lock +++ /dev/null @@ -1,131 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "7ec65c8fa8465c6b96387fed7814980773c8c767f3aaf01fe836a222e763c7a0" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.11" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.python.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "certifi": { - "hashes": [ - "sha256:0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14", - "sha256:90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382" - ], - "markers": "python_version >= '3.6'", - "version": "==2022.9.24" - }, - "chardet": { - "hashes": [ - "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", - "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" - ], - "version": "==3.0.4" - }, - "e1839a8": { - "editable": true, - "path": "." - }, - "gunicorn": { - "hashes": [ - "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e", - "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8" - ], - "markers": "python_version >= '3.5'", - "version": "==20.1.0" - }, - "idna": { - "hashes": [ - "sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e", - "sha256:684a38a6f903c1d71d6d5fac066b58d7768af4de2b832e426ec79c30daa94a16" - ], - "version": "==2.7" - }, - "requests": { - "hashes": [ - "sha256:99dcfdaaeb17caf6e526f32b6a7b780461512ab3f1d992187801694cba42770c", - "sha256:a84b8c9ab6239b578f22d1c21d51b696dcfe004032bb80ea832398d6909d7279" - ], - "index": "pypi", - "version": "==2.20.0" - }, - "setuptools": { - "hashes": [ - "sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54", - "sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75" - ], - "markers": "python_version >= '3.7'", - "version": "==65.6.3" - }, - "testapp": { - "editable": true, - "path": "." - }, - "urllib3": { - "hashes": [ - "sha256:2393a695cd12afedd0dcb26fe5d50d0cf248e5a66f75dbd89a3d4eb333a61af4", - "sha256:a637e5fae88995b256e3409dc4d52c2e2e0ba32c42a6365fee8bbd2238de3cfb" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' and python_version < '4'", - "version": "==1.24.3" - } - }, - "develop": { - "attrs": { - "hashes": [ - "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6", - "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c" - ], - "markers": "python_version >= '3.5'", - "version": "==22.1.0" - }, - "iniconfig": { - "hashes": [ - "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3", - "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32" - ], - "version": "==1.1.1" - }, - "packaging": { - "hashes": [ - "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb", - "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522" - ], - "markers": "python_version >= '3.6'", - "version": "==21.3" - }, - "pluggy": { - "hashes": [ - "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159", - "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3" - ], - "markers": "python_version >= '3.6'", - "version": "==1.0.0" - }, - "pyparsing": { - "hashes": [ - "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb", - "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc" - ], - "markers": "python_full_version >= '3.6.8'", - "version": "==3.0.9" - }, - "pytest": { - "hashes": [ - "sha256:892f933d339f068883b6fd5a459f03d85bfcb355e4981e146d2c7616c21fef71", - "sha256:c4014eb40e10f11f355ad4e3c2fb2c6c6d1919c73f3b5a433de4708202cade59" - ], - "index": "pypi", - "version": "==7.2.0" - } - } -} diff --git a/3.11/test/micropipenv-test-app/setup.py b/3.11/test/micropipenv-test-app/setup.py deleted file mode 100644 index e3134094..00000000 --- a/3.11/test/micropipenv-test-app/setup.py +++ /dev/null @@ -1,10 +0,0 @@ -from setuptools import setup, find_packages - - -setup ( - name = "testapp", - version = "0.1", - description = "Example application to be deployed.", - packages = find_packages(), - install_requires = ["gunicorn"], -) diff --git a/3.11/test/micropipenv-test-app/testapp.py b/3.11/test/micropipenv-test-app/testapp.py deleted file mode 100644 index fe200352..00000000 --- a/3.11/test/micropipenv-test-app/testapp.py +++ /dev/null @@ -1,12 +0,0 @@ -import sys -import requests - - -def application(environ, start_response): - start_response('200 OK', [('Content-Type', 'text/plain')]) - # Python 3.12 needed requests version bump - if sys.version_info.major == 3 and sys.version_info.minor >= 12: - assert requests.__version__ == '2.28.2' - else: - assert requests.__version__ == '2.20.0' - return [b"Hello from gunicorn WSGI application!"] diff --git a/3.11/test/mod-wsgi-test-app b/3.11/test/mod-wsgi-test-app deleted file mode 120000 index 9d8c3338..00000000 --- a/3.11/test/mod-wsgi-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/mod-wsgi-test-app \ No newline at end of file diff --git a/3.11/test/npm-virtualenv-uwsgi-test-app b/3.11/test/npm-virtualenv-uwsgi-test-app deleted file mode 120000 index b34ae21e..00000000 --- a/3.11/test/npm-virtualenv-uwsgi-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/npm-virtualenv-uwsgi-test-app \ No newline at end of file diff --git a/3.11/test/numpy-test-app b/3.11/test/numpy-test-app deleted file mode 120000 index b064f87f..00000000 --- a/3.11/test/numpy-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/numpy-test-app \ No newline at end of file diff --git a/3.11/test/pin-pipenv-version-test-app/.s2i/environment b/3.11/test/pin-pipenv-version-test-app/.s2i/environment deleted file mode 100644 index 9bfe6709..00000000 --- a/3.11/test/pin-pipenv-version-test-app/.s2i/environment +++ /dev/null @@ -1,2 +0,0 @@ -ENABLE_PIPENV=1 -PIN_PIPENV_VERSION=2021.5.29 diff --git a/3.11/test/pin-pipenv-version-test-app/app.sh b/3.11/test/pin-pipenv-version-test-app/app.sh deleted file mode 100755 index 4334c760..00000000 --- a/3.11/test/pin-pipenv-version-test-app/app.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -source .s2i/environment - -echo "Testing PIN_PIPENV_VERSION (set in .s2i/environment) ..." -pipenv_version=`pipenv --version` -expected="pipenv, version $PIN_PIPENV_VERSION" -if [ "$pipenv_version" != "$expected" ]; then - echo "ERROR: pipenv version is different than expected." - echo "Expected: ${expected}" - echo "Actual: ${pipenv_version}" - exit 1 -fi - -# Test the uwsgi server -exec uwsgi \ - --http-socket :8080 \ - --die-on-term \ - --master \ - --single-interpreter \ - --enable-threads \ - --threads=5 \ - --thunder-lock \ - --module wsgi diff --git a/3.11/test/pin-pipenv-version-test-app/requirements.txt b/3.11/test/pin-pipenv-version-test-app/requirements.txt deleted file mode 100644 index 66d42051..00000000 --- a/3.11/test/pin-pipenv-version-test-app/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -uWSGI -Flask diff --git a/3.11/test/pin-pipenv-version-test-app/wsgi.py b/3.11/test/pin-pipenv-version-test-app/wsgi.py deleted file mode 100644 index 96e1a614..00000000 --- a/3.11/test/pin-pipenv-version-test-app/wsgi.py +++ /dev/null @@ -1,9 +0,0 @@ -from flask import Flask -application = Flask(__name__) - -@application.route('/') -def hello(): - return b'Hello World from uWSGI hosted WSGI application!' - -if __name__ == '__main__': - application.run() diff --git a/3.11/test/pipenv-and-micropipenv-should-fail-test-app b/3.11/test/pipenv-and-micropipenv-should-fail-test-app deleted file mode 120000 index cf830645..00000000 --- a/3.11/test/pipenv-and-micropipenv-should-fail-test-app +++ /dev/null @@ -1 +0,0 @@ -../../src/test/pipenv-and-micropipenv-should-fail-test-app \ No newline at end of file diff --git a/3.11/test/pipenv-test-app/.gitignore b/3.11/test/pipenv-test-app/.gitignore deleted file mode 100644 index ba746605..00000000 --- a/3.11/test/pipenv-test-app/.gitignore +++ /dev/null @@ -1,57 +0,0 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] - -# C extensions -*.so - -# Distribution / packaging -.Python -env/ -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -*.egg-info/ -.installed.cfg -*.egg - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*,cover - -# Translations -*.mo -*.pot - -# Django stuff: -*.log - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ diff --git a/3.11/test/pipenv-test-app/.s2i/environment b/3.11/test/pipenv-test-app/.s2i/environment deleted file mode 100644 index 4a4f7605..00000000 --- a/3.11/test/pipenv-test-app/.s2i/environment +++ /dev/null @@ -1,2 +0,0 @@ -ENABLE_PIPENV=true -DISABLE_SETUP_PY_PROCESSING=true diff --git a/3.11/test/pipenv-test-app/Pipfile b/3.11/test/pipenv-test-app/Pipfile deleted file mode 100644 index 9944bb52..00000000 --- a/3.11/test/pipenv-test-app/Pipfile +++ /dev/null @@ -1,14 +0,0 @@ -[[source]] -url = "https://pypi.python.org/simple" -verify_ssl = true -name = "pypi" - -[packages] -"e1839a8" = {path = ".", editable = true} -requests = "==2.20.0" - -[dev-packages] -pytest = ">=2.8.0" - -[requires] -python_version = "3.11" diff --git a/3.11/test/pipenv-test-app/Pipfile.lock b/3.11/test/pipenv-test-app/Pipfile.lock deleted file mode 100644 index 7fc7c766..00000000 --- a/3.11/test/pipenv-test-app/Pipfile.lock +++ /dev/null @@ -1,131 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "7ec65c8fa8465c6b96387fed7814980773c8c767f3aaf01fe836a222e763c7a0" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.11" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.python.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "certifi": { - "hashes": [ - "sha256:0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14", - "sha256:90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382" - ], - "markers": "python_version >= '3.6'", - "version": "==2022.9.24" - }, - "chardet": { - "hashes": [ - "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", - "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" - ], - "version": "==3.0.4" - }, - "e1839a8": { - "editable": true, - "path": "." - }, - "gunicorn": { - "hashes": [ - "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e", - "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8" - ], - "markers": "python_version >= '3.5'", - "version": "==20.1.0" - }, - "idna": { - "hashes": [ - "sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e", - "sha256:684a38a6f903c1d71d6d5fac066b58d7768af4de2b832e426ec79c30daa94a16" - ], - "version": "==2.7" - }, - "requests": { - "hashes": [ - "sha256:99dcfdaaeb17caf6e526f32b6a7b780461512ab3f1d992187801694cba42770c", - "sha256:a84b8c9ab6239b578f22d1c21d51b696dcfe004032bb80ea832398d6909d7279" - ], - "index": "pypi", - "version": "==2.20.0" - }, - "setuptools": { - "hashes": [ - "sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54", - "sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75" - ], - "markers": "python_version >= '3.7'", - "version": "==65.6.3" - }, - "testapp": { - "editable": true, - "path": "." - }, - "urllib3": { - "hashes": [ - "sha256:2393a695cd12afedd0dcb26fe5d50d0cf248e5a66f75dbd89a3d4eb333a61af4", - "sha256:a637e5fae88995b256e3409dc4d52c2e2e0ba32c42a6365fee8bbd2238de3cfb" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' and python_version < '4'", - "version": "==1.24.3" - } - }, - "develop": { - "attrs": { - "hashes": [ - "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6", - "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c" - ], - "markers": "python_version >= '3.5'", - "version": "==22.1.0" - }, - "iniconfig": { - "hashes": [ - "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3", - "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32" - ], - "version": "==1.1.1" - }, - "packaging": { - "hashes": [ - "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb", - "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522" - ], - "markers": "python_version >= '3.6'", - "version": "==21.3" - }, - "pluggy": { - "hashes": [ - "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159", - "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3" - ], - "markers": "python_version >= '3.6'", - "version": "==1.0.0" - }, - "pyparsing": { - "hashes": [ - "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb", - "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc" - ], - "markers": "python_full_version >= '3.6.8'", - "version": "==3.0.9" - }, - "pytest": { - "hashes": [ - "sha256:892f933d339f068883b6fd5a459f03d85bfcb355e4981e146d2c7616c21fef71", - "sha256:c4014eb40e10f11f355ad4e3c2fb2c6c6d1919c73f3b5a433de4708202cade59" - ], - "index": "pypi", - "version": "==7.2.0" - } - } -} diff --git a/3.11/test/pipenv-test-app/setup.py b/3.11/test/pipenv-test-app/setup.py deleted file mode 100644 index e3134094..00000000 --- a/3.11/test/pipenv-test-app/setup.py +++ /dev/null @@ -1,10 +0,0 @@ -from setuptools import setup, find_packages - - -setup ( - name = "testapp", - version = "0.1", - description = "Example application to be deployed.", - packages = find_packages(), - install_requires = ["gunicorn"], -) diff --git a/3.11/test/pipenv-test-app/testapp.py b/3.11/test/pipenv-test-app/testapp.py deleted file mode 100644 index fe200352..00000000 --- a/3.11/test/pipenv-test-app/testapp.py +++ /dev/null @@ -1,12 +0,0 @@ -import sys -import requests - - -def application(environ, start_response): - start_response('200 OK', [('Content-Type', 'text/plain')]) - # Python 3.12 needed requests version bump - if sys.version_info.major == 3 and sys.version_info.minor >= 12: - assert requests.__version__ == '2.28.2' - else: - assert requests.__version__ == '2.20.0' - return [b"Hello from gunicorn WSGI application!"] diff --git a/3.11/test/poetry-src-layout-test-app b/3.11/test/poetry-src-layout-test-app deleted file mode 120000 index 92d2990d..00000000 --- a/3.11/test/poetry-src-layout-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/poetry-src-layout-test-app \ No newline at end of file diff --git a/3.11/test/pyuwsgi-pipenv-test-app/.s2i/environment b/3.11/test/pyuwsgi-pipenv-test-app/.s2i/environment deleted file mode 100644 index 9bfe6709..00000000 --- a/3.11/test/pyuwsgi-pipenv-test-app/.s2i/environment +++ /dev/null @@ -1,2 +0,0 @@ -ENABLE_PIPENV=1 -PIN_PIPENV_VERSION=2021.5.29 diff --git a/3.11/test/pyuwsgi-pipenv-test-app/app.sh b/3.11/test/pyuwsgi-pipenv-test-app/app.sh deleted file mode 100755 index 3a2680f2..00000000 --- a/3.11/test/pyuwsgi-pipenv-test-app/app.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -source .s2i/environment - -echo "Testing PIN_PIPENV_VERSION (set in .s2i/environment) ..." -pipenv_version=`pipenv --version` -expected="pipenv, version $PIN_PIPENV_VERSION" -if [ "$pipenv_version" != "$expected" ]; then - echo "ERROR: pipenv version is different than expected." - echo "Expected: ${expected}" - echo "Actual: ${pipenv_version}" - exit 1 -fi - -# Test the uwsgi server -exec uwsgi \ - --http-socket :8080 \ - --die-on-term \ - --master \ - --single-interpreter \ - --enable-threads \ - --threads=5 \ - --thunder-lock \ - --module wsgi diff --git a/3.11/test/pyuwsgi-pipenv-test-app/requirements.txt b/3.11/test/pyuwsgi-pipenv-test-app/requirements.txt deleted file mode 100644 index 932ba1d6..00000000 --- a/3.11/test/pyuwsgi-pipenv-test-app/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -pyuwsgi # this is just a copy of uwsgi project but it has wheels on PyPI -Flask diff --git a/3.11/test/pyuwsgi-pipenv-test-app/wsgi.py b/3.11/test/pyuwsgi-pipenv-test-app/wsgi.py deleted file mode 100644 index 96e1a614..00000000 --- a/3.11/test/pyuwsgi-pipenv-test-app/wsgi.py +++ /dev/null @@ -1,9 +0,0 @@ -from flask import Flask -application = Flask(__name__) - -@application.route('/') -def hello(): - return b'Hello World from uWSGI hosted WSGI application!' - -if __name__ == '__main__': - application.run() diff --git a/3.11/test/run b/3.11/test/run deleted file mode 100755 index 134639eb..00000000 --- a/3.11/test/run +++ /dev/null @@ -1,312 +0,0 @@ -#!/bin/bash -# -# The 'run' performs a simple test that verifies that S2I image. -# The main focus here is to excersise the S2I scripts. -# -# IMAGE_NAME specifies a name of the candidate image used for testing. -# The image has to be available before this script is executed. -# -declare -a COMMON_WEB_APPS=({gunicorn-config-different-port,gunicorn-different-port,django-different-port,standalone,setup,setup-requirements,django,numpy,app-home,locale,pipenv,pipenv-and-micropipenv-should-fail,app-module,pyuwsgi-pipenv,micropipenv,standalone-custom-pypi-index,gunicorn-python-configfile-different-port}-test-app) -declare -a FULL_WEB_APPS=({setup-cfg,npm-virtualenv-uwsgi,mod-wsgi,pin-pipenv-version,micropipenv-requirements,poetry-src-layout}-test-app) -declare -a MINIMAL_WEB_APPS=() -declare -a WEB_APPS=(${COMMON_WEB_APPS[@]} ${FULL_WEB_APPS[@]}) - -# Some tests, like the one using the latest pipenv, might be unstable -# because new upstream releases tend to break our tests sometimes. -# If a test is in UNSTABLE_TESTS and IGNORE_UNSTABLE_TESTS env -# variable is defined, a result of the test has no impact on -# the overall result of the test suite. -# -# Reasons for specific tests to be marked as unstable: -# pipenv-test-app: -# - this testcase installs pipenv from the internet. -# Problem is that the upstream releases are from time-to-time broken -# which breaks this test. We generally want to know about it -# in upstream, but ignore this in downstream. -declare -a UNSTABLE_TESTS=(pipenv-test-app) - -# TODO: Make command compatible for Mac users -test_dir="$(readlink -f $(dirname "${BASH_SOURCE[0]}"))" -image_dir=$(readlink -f ${test_dir}/..) - -TEST_LIST="\ -test_s2i_usage -test_docker_run_usage -test_application -test_application_with_user -test_application_enable_init_wrapper -" - -TEST_VAR_DOCKER="\ -test_from_dockerfile -" - -if [[ -z $VERSION ]]; then - echo "ERROR: The VERSION variable must be set." - ct_check_testcase_result 1 - exit 1 -fi - -IMAGE_NAME=${IMAGE_NAME:-ubi9/python-${VERSION//./}} - -. test/test-lib.sh - -info() { - echo -e "\n\e[1m[INFO] $@\e[0m\n" -} - -image_exists() { - docker inspect $1 &>/dev/null -} - -container_exists() { - image_exists $(cat $cid_file) -} - - -container_ip() { - docker inspect --format="{{ .NetworkSettings.IPAddress }}" $(cat $cid_file) -} - -run_s2i_build() { - info "Building the ${1} application image ..." - ct_s2i_build_as_df file://${test_dir}/${1} ${IMAGE_NAME} ${IMAGE_NAME}-testapp ${s2i_args} -} - -prepare() { - if ! image_exists ${IMAGE_NAME}; then - echo "ERROR: The image ${IMAGE_NAME} must exist before this script is executed." - return 1 - fi - # TODO: S2I build require the application is a valid 'GIT' repository, we - # should remove this restriction in the future when a file:// is used. - info "Preparing to test ${1} ..." - pushd ${test_dir}/${1} >/dev/null - git init - git config user.email "build@localhost" && git config user.name "builder" - git add -A && git commit -m "Sample commit" - popd >/dev/null -} - -run_test_application() { - docker run --user=100001 ${CONTAINER_ARGS} --rm --cidfile=${cid_file} ${IMAGE_NAME}-testapp -} - -cleanup() { - info "Cleaning up the test application image" - if image_exists ${IMAGE_NAME}-testapp; then - docker rmi -f ${IMAGE_NAME}-testapp - fi - rm -rf ${test_dir}/${1}/.git -} -wait_for_cid() { - local max_attempts=10 - local sleep_time=1 - local attempt=1 - info "Waiting for application container to start $CONTAINER_ARGS ..." - while [ $attempt -le $max_attempts ]; do - [ -f $cid_file ] && [ -s $cid_file ] && return 0 - attempt=$(( $attempt + 1 )) - sleep $sleep_time - done - return 1 -} - -test_s2i_usage() { - info "Testing 's2i usage' ..." - ct_s2i_usage ${IMAGE_NAME} ${s2i_args} 1>/dev/null -} - -test_docker_run_usage() { - info "Testing 'docker run' usage ..." - docker run --rm ${IMAGE_NAME} &>/dev/null -} - -test_scl_usage() { - local run_cmd="$1" - local expected="$2" - local cid_file="$3" - - info "Testing command availability in the image" - out=$(docker run --rm ${IMAGE_NAME} /bin/bash -c "${run_cmd}" 2>&1) - if ! echo "${out}" | grep -q "${expected}"; then - echo "ERROR[/bin/bash -c "${run_cmd}"] Expected '${expected}', got '${out}'" - return 1 - fi - out=$(docker exec $(cat ${cid_file}) /bin/bash -c "${run_cmd}" 2>&1) - if ! echo "${out}" | grep -q "${expected}"; then - echo "ERROR[exec /bin/bash -c "${run_cmd}"] Expected '${expected}', got '${out}'" - return 1 - fi - out=$(docker exec $(cat ${cid_file}) /bin/sh -ic "${run_cmd}" 2>&1) - if ! echo "${out}" | grep -q "${expected}"; then - echo "ERROR[exec /bin/sh -ic "${run_cmd}"] Expected '${expected}', got '${out}'" - return 1 - fi -} - -test_connection() { - info "Testing the HTTP connection (http://$(container_ip):${test_port}) ${CONTAINER_ARGS} ..." - local max_attempts=30 - local sleep_time=1 - local attempt=1 - local result=1 - while [ $attempt -le $max_attempts ]; do - response_code=$(curl -s -w %{http_code} -o /dev/null http://$(container_ip):${test_port}/) - status=$? - if [ $status -eq 0 ]; then - if [ $response_code -eq 200 ]; then - result=0 - fi - break - fi - attempt=$(( $attempt + 1 )) - sleep $sleep_time - done - return $result -} - -test_application() { - local cid_file="$CID_FILE_DIR"/"$(mktemp -u -p . --suffix .cid)" - # Verify that the HTTP connection can be established to test application container - run_test_application & - - # Wait for the container to write it's CID file - wait_for_cid - # Some test apps have tests in their startup code so we have to check - # that the container starts at all - ct_check_testcase_result $? - - # Instead of relying on VERSION variable coming from Makefile - # set the expected string based on the PYTHON_VERSION defined - # inside the running container. - python_version=$(docker run --rm $IMAGE_NAME /bin/bash -c "echo \$PYTHON_VERSION" 2>&1) - - test_scl_usage "python --version" "Python $python_version." "${cid_file}" - ct_check_testcase_result $? - test_scl_usage "node --version" "^v[0-9]*\.[0-9]*\.[0-9]*" "${cid_file}" - ct_check_testcase_result $? - test_scl_usage "npm --version" "^[0-9]*\.[0-9]*\.[0-9]*" "${cid_file}" - ct_check_testcase_result $? - test_connection - ct_check_testcase_result $? - container_exists && docker stop $(cat "$cid_file") -} - -test_from_dockerfile(){ - info "Test from Dockerfile" - # Django 4.2 supports Python 3.9+ - django_example_repo_url="https://github.com/sclorg/django-ex.git@4.2.x" - - ct_test_app_dockerfile $test_dir/from-dockerfile/Dockerfile.tpl $django_example_repo_url 'Welcome to your Django application on OpenShift' app-src - ct_check_testcase_result $? - - info "Test from Dockerfile with no s2i scripts used" - ct_test_app_dockerfile $test_dir/from-dockerfile/Dockerfile_no_s2i.tpl $django_example_repo_url 'Welcome to your Django application on OpenShift' app-src - ct_check_testcase_result $? -} - -test_from_dockerfile_minimal(){ - info "Test from Dockerfile" - - # The following tests are for multi-stage builds. These technically also work on full images, but there is no reason to do multi-stage builds with full images. - - # uwsgi in uwsgi-test-app - ct_test_app_dockerfile $test_dir/from-dockerfile/uwsgi.Dockerfile.tpl $test_dir/uwsgi-test-app 'Hello World from uWSGI hosted WSGI application!' app-src - ct_check_testcase_result $? - - # So far, for all the minimal images, the name of the full container image counterpart - # is the same just without -minimal infix. - # sclorg/python-39-minimal-c9s / sclorg/python-39-c9s - # ubi8/python-39-minimal / ubi8/python-39 - FULL_IMAGE_NAME=${IMAGE_NAME/-minimal/} - - if ct_pull_image "$FULL_IMAGE_NAME"; then - # mod_wsgi in micropipenv-requirements-test-app - sed "s@#IMAGE_NAME#@${IMAGE_NAME}@;s@#FULL_IMAGE_NAME#@${FULL_IMAGE_NAME}@" $test_dir/from-dockerfile/mod_wsgi.Dockerfile.tpl > $test_dir/from-dockerfile/Dockerfile - ct_test_app_dockerfile $test_dir/from-dockerfile/Dockerfile $test_dir/micropipenv-requirements-test-app 'Hello World from mod_wsgi hosted WSGI application!' app-src - ct_check_testcase_result $? - else - echo "[SKIP] Multistage build from Dockerfile - $FULL_IMAGE_NAME does not exists." - fi - -} - -test_application_with_user() { - # test application with random user - CONTAINER_ARGS="--user 12345" test_application - -} - -test_application_enable_init_wrapper() { - # test application with init wrapper - CONTAINER_ARGS="-e ENABLE_INIT_WRAPPER=true" test_application -} - -# Positive test & non-zero exit status = ERROR. -# Negative test & zero exit status = ERROR. -# Tests with '-should-fail-' in their name should fail during a build, -# expecting non-zero exit status. -evaluate_build_result() { - local _result="$1" - local _app="$2" - local _type="positive" - local _test_msg="[PASSED]" - local _ret_code=0 - - if [[ "$_app" == *"-should-fail-"* ]]; then - _type="negative" - fi - - if [[ "$_type" == "positive" && "$_result" != "0" ]]; then - info "TEST FAILED (${_type}), EXPECTED:0 GOT:${_result}" - _ret_code=$_result - elif [[ "$_type" == "negative" && "$_result" == "0" ]]; then - info "TEST FAILED (${_type}), EXPECTED: non-zero GOT:${_result}" - _ret_code=1 - fi - if [ $_ret_code != 0 ]; then - cleanup - TESTSUITE_RESULT=1 - _test_msg="[FAILED]" - fi - ct_update_test_result "$_test_msg" "$_app" run_s2i_build - - if [[ "$_type" == "negative" && "$_result" != "0" ]]; then - _ret_code=127 # even though this is success, the app is still not built - fi - return $_ret_code -} - -ct_init - -# For debugging purposes, this script can be run with one or more arguments -# those arguments list is a sub-set of values in the WEB_APPS array defined above -# Example: ./run app-home-test-app pipenv-test-app -for app in ${@:-${WEB_APPS[@]}}; do - # Since we built the candidate image locally, we don't want S2I attempt to pull - # it from Docker hub - s2i_args="--pull-policy=never" - - # Example apps with "-different-port-" in their name don't use the default port 8080 - if [[ "$app" == *"-different-port-"* ]]; then - test_port=8085 - else - test_port=8080 - fi - - prepare ${app} - if [ $? -ne 0 ]; then - ct_update_test_result "[FAILED]" "${app}" "preparation" - TESTSUITE_RESULT=1 - continue - fi - run_s2i_build ${app} - evaluate_build_result $? "$app" || continue - - TEST_SET=${TESTS:-$TEST_LIST} ct_run_tests_from_testset "${app}" - - cleanup ${app} -done - -TEST_SET=${TESTS:-$TEST_VAR_DOCKER} ct_run_tests_from_testset "var-docker" diff --git a/3.11/test/run-openshift-pytest b/3.11/test/run-openshift-pytest deleted file mode 120000 index 5063ae30..00000000 --- a/3.11/test/run-openshift-pytest +++ /dev/null @@ -1 +0,0 @@ -../../test/run-openshift-pytest \ No newline at end of file diff --git a/3.11/test/run-pytest b/3.11/test/run-pytest deleted file mode 100755 index 9810fe89..00000000 --- a/3.11/test/run-pytest +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -# -# IMAGE_NAME specifies a name of the candidate image used for testing. -# The image has to be available before this script is executed. -# SINGLE_VERSION specifies the major version of the MariaDB in format of X.Y -# OS specifies RHEL version (e.g. OS=rhel8) -# - -THISDIR=$(dirname ${BASH_SOURCE[0]}) - -if python3 -c 'import sys; sys.exit(0 if sys.version_info < (3,13) else 1)'; then - PYTHON_VERSION="3.12" -else - PYTHON_VERSION="3" -fi -cd "${THISDIR}" && "python${PYTHON_VERSION}" -m pytest -s -rA --showlocals -vv test_container_*.py diff --git a/3.11/test/setup-cfg-test-app b/3.11/test/setup-cfg-test-app deleted file mode 120000 index 71a2b0cb..00000000 --- a/3.11/test/setup-cfg-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/setup-cfg-test-app \ No newline at end of file diff --git a/3.11/test/setup-requirements-test-app b/3.11/test/setup-requirements-test-app deleted file mode 120000 index c909ccb9..00000000 --- a/3.11/test/setup-requirements-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/setup-requirements-test-app \ No newline at end of file diff --git a/3.11/test/setup-test-app b/3.11/test/setup-test-app deleted file mode 120000 index 1b49f26f..00000000 --- a/3.11/test/setup-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/setup-test-app \ No newline at end of file diff --git a/3.11/test/standalone-custom-pypi-index-test-app b/3.11/test/standalone-custom-pypi-index-test-app deleted file mode 120000 index 12941a9a..00000000 --- a/3.11/test/standalone-custom-pypi-index-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/standalone-custom-pypi-index-test-app \ No newline at end of file diff --git a/3.11/test/standalone-test-app b/3.11/test/standalone-test-app deleted file mode 120000 index 3f158948..00000000 --- a/3.11/test/standalone-test-app +++ /dev/null @@ -1 +0,0 @@ -../../examples/standalone-test-app \ No newline at end of file diff --git a/3.11/test/test-lib.sh b/3.11/test/test-lib.sh deleted file mode 120000 index 1ac99b93..00000000 --- a/3.11/test/test-lib.sh +++ /dev/null @@ -1 +0,0 @@ -../../common/test-lib.sh \ No newline at end of file diff --git a/3.11/test/test_container_application.py b/3.11/test/test_container_application.py deleted file mode 120000 index 25c1c1ec..00000000 --- a/3.11/test/test_container_application.py +++ /dev/null @@ -1 +0,0 @@ -../../test/test_container_application.py \ No newline at end of file diff --git a/3.11/test/test_container_basics.py b/3.11/test/test_container_basics.py deleted file mode 120000 index b85dc139..00000000 --- a/3.11/test/test_container_basics.py +++ /dev/null @@ -1 +0,0 @@ -../../test/test_container_basics.py \ No newline at end of file diff --git a/3.11/test/test_ocp_deploy_templates.py b/3.11/test/test_ocp_deploy_templates.py deleted file mode 120000 index 0b821390..00000000 --- a/3.11/test/test_ocp_deploy_templates.py +++ /dev/null @@ -1 +0,0 @@ -../../test/test_ocp_deploy_templates.py \ No newline at end of file diff --git a/3.11/test/test_ocp_helm_python_django_app.py b/3.11/test/test_ocp_helm_python_django_app.py deleted file mode 120000 index 34b4f0dd..00000000 --- a/3.11/test/test_ocp_helm_python_django_app.py +++ /dev/null @@ -1 +0,0 @@ -../../test/test_ocp_helm_python_django_app.py \ No newline at end of file diff --git a/3.11/test/test_ocp_helm_python_django_psql_persistent.py b/3.11/test/test_ocp_helm_python_django_psql_persistent.py deleted file mode 120000 index 64d2105d..00000000 --- a/3.11/test/test_ocp_helm_python_django_psql_persistent.py +++ /dev/null @@ -1 +0,0 @@ -../../test/test_ocp_helm_python_django_psql_persistent.py \ No newline at end of file diff --git a/3.11/test/test_ocp_helm_python_imagestreams.py b/3.11/test/test_ocp_helm_python_imagestreams.py deleted file mode 120000 index 0022607f..00000000 --- a/3.11/test/test_ocp_helm_python_imagestreams.py +++ /dev/null @@ -1 +0,0 @@ -../../test/test_ocp_helm_python_imagestreams.py \ No newline at end of file diff --git a/3.11/test/test_ocp_imagestreams_quickstart.py b/3.11/test/test_ocp_imagestreams_quickstart.py deleted file mode 120000 index 18f8d7e2..00000000 --- a/3.11/test/test_ocp_imagestreams_quickstart.py +++ /dev/null @@ -1 +0,0 @@ -../../test/test_ocp_imagestreams_quickstart.py \ No newline at end of file diff --git a/3.11/test/test_ocp_python_ex_standalone.py b/3.11/test/test_ocp_python_ex_standalone.py deleted file mode 120000 index bb6022f7..00000000 --- a/3.11/test/test_ocp_python_ex_standalone.py +++ /dev/null @@ -1 +0,0 @@ -../../test/test_ocp_python_ex_standalone.py \ No newline at end of file diff --git a/3.11/test/test_ocp_python_ex_template.py b/3.11/test/test_ocp_python_ex_template.py deleted file mode 120000 index b75080ca..00000000 --- a/3.11/test/test_ocp_python_ex_template.py +++ /dev/null @@ -1 +0,0 @@ -../../test/test_ocp_python_ex_template.py \ No newline at end of file diff --git a/Makefile b/Makefile index 434f35e0..e366bf6a 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # Variables are documented in common/build.sh. BASE_IMAGE_NAME = python -VERSIONS = 3.6 3.9 3.9-minimal 3.11 3.11-minimal 3.12 3.12-minimal 3.13 3.13-minimal 3.14 3.14-minimal +VERSIONS = 3.6 3.9 3.9-minimal 3.12 3.12-minimal 3.13 3.13-minimal 3.14 3.14-minimal OPENSHIFT_NAMESPACES = DOCKER_BUILD_CONTEXT = .. diff --git a/README.md b/README.md index 1b9d3d3d..92b88341 100644 --- a/README.md +++ b/README.md @@ -46,8 +46,6 @@ Table start |3.6||||
`registry.redhat.io/rhel8/python-36`
||| |3.9|
`quay.io/sclorg/python-39-c9s`
||||
`registry.redhat.io/rhel9/python-39`
|| |3.9-minimal|
`quay.io/sclorg/python-39-minimal-c9s`
|||||| -|3.11|
`quay.io/sclorg/python-311-c9s`
|||
`registry.redhat.io/rhel8/python-311`
|
`registry.redhat.io/rhel9/python-311`
|| -|3.11-minimal|
`quay.io/sclorg/python-311-minimal-c9s`
|||
`registry.redhat.io/rhel8/python-311-minimal`
||| |3.12|
`quay.io/sclorg/python-312-c9s`
|
`quay.io/sclorg/python-312-c10s`
||
`registry.redhat.io/rhel8/python-312`
|
`registry.redhat.io/rhel9/python-312`
|| |3.12-minimal|
`quay.io/sclorg/python-312-minimal-c9s`
|
`quay.io/sclorg/python-312-minimal-c10s`
||
`registry.redhat.io/rhel8/python-312-minimal`
|
`registry.redhat.io/rhel9/python-312-minimal`
|
`registry.redhat.io/rhel10/python-312-minimal`
| |3.13||
`quay.io/sclorg/python-313-c10s`
|
`quay.io/fedora/python-313`
|||| diff --git a/imagestreams/imagestreams.yaml b/imagestreams/imagestreams.yaml index 117192a5..9c1a5144 100644 --- a/imagestreams/imagestreams.yaml +++ b/imagestreams/imagestreams.yaml @@ -13,10 +13,10 @@ latest: "3.12-ubi9" distros: - name: UBI 8 - app_versions: ["3.6", "3.9", "3.11", "3.12"] + app_versions: ["3.6", "3.9"] - name: UBI 9 - app_versions: ["3.9", "3.11", "3.12", "3.12-minimal"] + app_versions: ["3.9", "3.12-minimal"] - name: UBI 10 app_versions: ["3.12-minimal"] @@ -25,10 +25,10 @@ latest: "3.12-ubi8" distros: - name: UBI 8 - app_versions: ["3.6", "3.9", "3.11", "3.12"] + app_versions: ["3.6", "3.9"] - name: UBI 9 - app_versions: ["3.9", "3.11", "3.12", "3.12-minimal"] + app_versions: ["3.9", "3.12-minimal"] - name: UBI 10 app_versions: ["3.12-minimal"] @@ -37,10 +37,10 @@ latest: "3.12-ubi8" distros: - name: UBI 8 - app_versions: ["3.6", "3.9", "3.11", "3.12"] + app_versions: ["3.6", "3.9"] - name: UBI 9 - app_versions: ["3.9", "3.11", "3.12", "3.12-minimal"] + app_versions: ["3.9", "3.12-minimal"] - name: UBI 10 app_versions: ["3.12-minimal"] diff --git a/imagestreams/python-centos.json b/imagestreams/python-centos.json index 2b7f3264..137fc78e 100644 --- a/imagestreams/python-centos.json +++ b/imagestreams/python-centos.json @@ -47,44 +47,6 @@ "type": "Local" } }, - { - "name": "3.11-ubi8", - "annotations": { - "openshift.io/display-name": "Python 3.11 (UBI 8)", - "openshift.io/provider-display-name": "Red Hat, Inc.", - "description": "Build and run Python 3.11 applications on UBI 8. For more information about using this builder image, including OpenShift considerations, see https://github.com/sclorg/s2i-python-container/blob/master/3.11/README.md.", - "iconClass": "icon-python", - "tags": "builder,python", - "version": "3.11", - "sampleRepo": "https://github.com/sclorg/django-ex.git" - }, - "from": { - "kind": "DockerImage", - "name": "registry.access.redhat.com/ubi8/python-311:latest" - }, - "referencePolicy": { - "type": "Local" - } - }, - { - "name": "3.12-ubi8", - "annotations": { - "openshift.io/display-name": "Python 3.12 (UBI 8)", - "openshift.io/provider-display-name": "Red Hat, Inc.", - "description": "Build and run Python 3.12 applications on UBI 8. For more information about using this builder image, including OpenShift considerations, see https://github.com/sclorg/s2i-python-container/blob/master/3.12/README.md.", - "iconClass": "icon-python", - "tags": "builder,python", - "version": "3.12", - "sampleRepo": "https://github.com/sclorg/django-ex.git" - }, - "from": { - "kind": "DockerImage", - "name": "registry.access.redhat.com/ubi8/python-312:latest" - }, - "referencePolicy": { - "type": "Local" - } - }, { "name": "3.9-ubi9", "annotations": { @@ -104,25 +66,6 @@ "type": "Local" } }, - { - "name": "3.11-ubi9", - "annotations": { - "openshift.io/display-name": "Python 3.11 (UBI 9)", - "openshift.io/provider-display-name": "Red Hat, Inc.", - "description": "Build and run Python 3.11 applications on UBI 9. For more information about using this builder image, including OpenShift considerations, see https://github.com/sclorg/s2i-python-container/blob/master/3.11/README.md.", - "iconClass": "icon-python", - "tags": "builder,python", - "version": "3.11", - "sampleRepo": "https://github.com/sclorg/django-ex.git" - }, - "from": { - "kind": "DockerImage", - "name": "registry.access.redhat.com/ubi9/python-311:latest" - }, - "referencePolicy": { - "type": "Local" - } - }, { "name": "3.12-ubi9", "annotations": { diff --git a/imagestreams/python-rhel-aarch64.json b/imagestreams/python-rhel-aarch64.json index 84aec37e..111b7444 100644 --- a/imagestreams/python-rhel-aarch64.json +++ b/imagestreams/python-rhel-aarch64.json @@ -47,44 +47,6 @@ "type": "Local" } }, - { - "name": "3.11-ubi8", - "annotations": { - "openshift.io/display-name": "Python 3.11 (UBI 8)", - "openshift.io/provider-display-name": "Red Hat, Inc.", - "description": "Build and run Python 3.11 applications on UBI 8. For more information about using this builder image, including OpenShift considerations, see https://github.com/sclorg/s2i-python-container/blob/master/3.11/README.md.", - "iconClass": "icon-python", - "tags": "builder,python", - "version": "3.11", - "sampleRepo": "https://github.com/sclorg/django-ex.git" - }, - "from": { - "kind": "DockerImage", - "name": "registry.redhat.io/ubi8/python-311:latest" - }, - "referencePolicy": { - "type": "Local" - } - }, - { - "name": "3.12-ubi8", - "annotations": { - "openshift.io/display-name": "Python 3.12 (UBI 8)", - "openshift.io/provider-display-name": "Red Hat, Inc.", - "description": "Build and run Python 3.12 applications on UBI 8. For more information about using this builder image, including OpenShift considerations, see https://github.com/sclorg/s2i-python-container/blob/master/3.12/README.md.", - "iconClass": "icon-python", - "tags": "builder,python", - "version": "3.12", - "sampleRepo": "https://github.com/sclorg/django-ex.git" - }, - "from": { - "kind": "DockerImage", - "name": "registry.redhat.io/ubi8/python-312:latest" - }, - "referencePolicy": { - "type": "Local" - } - }, { "name": "3.9-ubi9", "annotations": { @@ -104,25 +66,6 @@ "type": "Local" } }, - { - "name": "3.11-ubi9", - "annotations": { - "openshift.io/display-name": "Python 3.11 (UBI 9)", - "openshift.io/provider-display-name": "Red Hat, Inc.", - "description": "Build and run Python 3.11 applications on UBI 9. For more information about using this builder image, including OpenShift considerations, see https://github.com/sclorg/s2i-python-container/blob/master/3.11/README.md.", - "iconClass": "icon-python", - "tags": "builder,python", - "version": "3.11", - "sampleRepo": "https://github.com/sclorg/django-ex.git" - }, - "from": { - "kind": "DockerImage", - "name": "registry.redhat.io/ubi9/python-311:latest" - }, - "referencePolicy": { - "type": "Local" - } - }, { "name": "3.12-ubi9", "annotations": { diff --git a/imagestreams/python-rhel.json b/imagestreams/python-rhel.json index 84aec37e..111b7444 100644 --- a/imagestreams/python-rhel.json +++ b/imagestreams/python-rhel.json @@ -47,44 +47,6 @@ "type": "Local" } }, - { - "name": "3.11-ubi8", - "annotations": { - "openshift.io/display-name": "Python 3.11 (UBI 8)", - "openshift.io/provider-display-name": "Red Hat, Inc.", - "description": "Build and run Python 3.11 applications on UBI 8. For more information about using this builder image, including OpenShift considerations, see https://github.com/sclorg/s2i-python-container/blob/master/3.11/README.md.", - "iconClass": "icon-python", - "tags": "builder,python", - "version": "3.11", - "sampleRepo": "https://github.com/sclorg/django-ex.git" - }, - "from": { - "kind": "DockerImage", - "name": "registry.redhat.io/ubi8/python-311:latest" - }, - "referencePolicy": { - "type": "Local" - } - }, - { - "name": "3.12-ubi8", - "annotations": { - "openshift.io/display-name": "Python 3.12 (UBI 8)", - "openshift.io/provider-display-name": "Red Hat, Inc.", - "description": "Build and run Python 3.12 applications on UBI 8. For more information about using this builder image, including OpenShift considerations, see https://github.com/sclorg/s2i-python-container/blob/master/3.12/README.md.", - "iconClass": "icon-python", - "tags": "builder,python", - "version": "3.12", - "sampleRepo": "https://github.com/sclorg/django-ex.git" - }, - "from": { - "kind": "DockerImage", - "name": "registry.redhat.io/ubi8/python-312:latest" - }, - "referencePolicy": { - "type": "Local" - } - }, { "name": "3.9-ubi9", "annotations": { @@ -104,25 +66,6 @@ "type": "Local" } }, - { - "name": "3.11-ubi9", - "annotations": { - "openshift.io/display-name": "Python 3.11 (UBI 9)", - "openshift.io/provider-display-name": "Red Hat, Inc.", - "description": "Build and run Python 3.11 applications on UBI 9. For more information about using this builder image, including OpenShift considerations, see https://github.com/sclorg/s2i-python-container/blob/master/3.11/README.md.", - "iconClass": "icon-python", - "tags": "builder,python", - "version": "3.11", - "sampleRepo": "https://github.com/sclorg/django-ex.git" - }, - "from": { - "kind": "DockerImage", - "name": "registry.redhat.io/ubi9/python-311:latest" - }, - "referencePolicy": { - "type": "Local" - } - }, { "name": "3.12-ubi9", "annotations": { diff --git a/specs/multispec.yml b/specs/multispec.yml index 1d7de8d9..2486f3e0 100644 --- a/specs/multispec.yml +++ b/specs/multispec.yml @@ -23,11 +23,9 @@ specs: '{{ spec.pkg_prefix }}-setuptools', '{{ spec.pkg_prefix }}-pip'] "default": ['{{ spec.pkg_prefix }}', '{{ spec.pkg_prefix }}-devel', '{{ spec.pkg_prefix }}-setuptools', '{{ spec.pkg_prefix }}-pip'] - "3.11": ['{{ spec.pkg_prefix }}', '{{ spec.pkg_prefix }}-devel', - '{{ spec.pkg_prefix }}-setuptools', '{{ spec.pkg_prefix }}-pip'] "3.12": ['{{ spec.pkg_prefix }}', '{{ spec.pkg_prefix }}-devel', '{{ spec.pkg_prefix }}-setuptools', '{{ spec.pkg_prefix }}-pip'] - ubi_versions: ['3.6', '3.9', '3.11', '3.12'] + ubi_versions: ['3.6', '3.9', '3.12'] rhel9: distros: @@ -44,10 +42,9 @@ specs: 'mod_auth_gssapi', 'mod_ldap', 'mod_session', 'atlas-devel', 'gcc-gfortran', 'libffi-devel', 'libtool-ltdl', 'enchant', 'krb5-devel'] - ubi_versions: ['3.9', '3.11', '3.12', '3.14'] + ubi_versions: ['3.9', '3.12', '3.14'] extra_pkgs: "3.9": ['python3', 'python3-devel', 'python3-setuptools', 'python3-pip'] - "3.11": ['python3.11', 'python3.11-devel', 'python3.11-pip'] "3.12": ['python3.12', 'python3.12-devel', 'python3.12-pip'] "3.14": ['python3.14', 'python3.14-devel', 'python3.14-pip'] @@ -88,7 +85,6 @@ specs: 'krb5-devel'] extra_pkgs: "3.9": ['python3', 'python3-devel', 'python3-setuptools', 'python3-pip'] - "3.11": ['python3.11', 'python3.11-devel', 'python3.11-pip'] "3.12": ['python3.12', 'python3.12-devel', 'python3.12-pip'] "3.14": ['python3.14', 'python3.14-devel', 'python3.14-pip'] @@ -201,26 +197,6 @@ specs: pkg_prefix: "python3.12" main_image: "registry.access.redhat.com/ubi9/python-312" - "3.11": - version: "3.11" - short_ver: "311" - minimal: false - base_img_version: "1" - # Python 3.11 doesn't come as a module - module_stream: "" - pkg_prefix: "python3.11" - main_image: "registry.access.redhat.com/ubi9/python-311" - - "3.11-minimal": - version: "3.11" - short_ver: "311" - minimal: true - base_img_version: "1" - # Python 3.11 doesn't come as a module - module_stream: "" - pkg_prefix: "python3.11" - main_image: "quay.io/sclorg/python-311-minimal-c9s" - "3.9": version: "3.9" short_ver: "39" @@ -260,15 +236,6 @@ matrix: - distros: - centos-stream-9-x86_64 version: "3.9-minimal" - - distros: - - centos-stream-9-x86_64 - - rhel-9-x86_64 - - rhel-8-x86_64 - version: "3.11" - - distros: - - centos-stream-9-x86_64 - - rhel-8-x86_64 - version: "3.11-minimal" - distros: - centos-stream-10-x86_64 - centos-stream-9-x86_64 diff --git a/src/test/pin-pipenv-version-test-app/.s2i/environment b/src/test/pin-pipenv-version-test-app/.s2i/environment index 5289f772..d859ce70 100644 --- a/src/test/pin-pipenv-version-test-app/.s2i/environment +++ b/src/test/pin-pipenv-version-test-app/.s2i/environment @@ -1,5 +1,5 @@ ENABLE_PIPENV=1 -{% if spec.version in ["3.6", "3.8", "3.9", "3.10", "3.11"] %} +{% if spec.version in ["3.6", "3.8", "3.9"] %} PIN_PIPENV_VERSION=2021.5.29 {% elif spec.version in ["3.12", "3.13"] %} PIN_PIPENV_VERSION=2023.11.14 diff --git a/src/test/pipenv-test-app/3.11/Pipfile.lock b/src/test/pipenv-test-app/3.11/Pipfile.lock deleted file mode 100644 index 7fc7c766..00000000 --- a/src/test/pipenv-test-app/3.11/Pipfile.lock +++ /dev/null @@ -1,131 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "7ec65c8fa8465c6b96387fed7814980773c8c767f3aaf01fe836a222e763c7a0" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.11" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.python.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "certifi": { - "hashes": [ - "sha256:0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14", - "sha256:90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382" - ], - "markers": "python_version >= '3.6'", - "version": "==2022.9.24" - }, - "chardet": { - "hashes": [ - "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", - "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" - ], - "version": "==3.0.4" - }, - "e1839a8": { - "editable": true, - "path": "." - }, - "gunicorn": { - "hashes": [ - "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e", - "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8" - ], - "markers": "python_version >= '3.5'", - "version": "==20.1.0" - }, - "idna": { - "hashes": [ - "sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e", - "sha256:684a38a6f903c1d71d6d5fac066b58d7768af4de2b832e426ec79c30daa94a16" - ], - "version": "==2.7" - }, - "requests": { - "hashes": [ - "sha256:99dcfdaaeb17caf6e526f32b6a7b780461512ab3f1d992187801694cba42770c", - "sha256:a84b8c9ab6239b578f22d1c21d51b696dcfe004032bb80ea832398d6909d7279" - ], - "index": "pypi", - "version": "==2.20.0" - }, - "setuptools": { - "hashes": [ - "sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54", - "sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75" - ], - "markers": "python_version >= '3.7'", - "version": "==65.6.3" - }, - "testapp": { - "editable": true, - "path": "." - }, - "urllib3": { - "hashes": [ - "sha256:2393a695cd12afedd0dcb26fe5d50d0cf248e5a66f75dbd89a3d4eb333a61af4", - "sha256:a637e5fae88995b256e3409dc4d52c2e2e0ba32c42a6365fee8bbd2238de3cfb" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' and python_version < '4'", - "version": "==1.24.3" - } - }, - "develop": { - "attrs": { - "hashes": [ - "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6", - "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c" - ], - "markers": "python_version >= '3.5'", - "version": "==22.1.0" - }, - "iniconfig": { - "hashes": [ - "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3", - "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32" - ], - "version": "==1.1.1" - }, - "packaging": { - "hashes": [ - "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb", - "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522" - ], - "markers": "python_version >= '3.6'", - "version": "==21.3" - }, - "pluggy": { - "hashes": [ - "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159", - "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3" - ], - "markers": "python_version >= '3.6'", - "version": "==1.0.0" - }, - "pyparsing": { - "hashes": [ - "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb", - "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc" - ], - "markers": "python_full_version >= '3.6.8'", - "version": "==3.0.9" - }, - "pytest": { - "hashes": [ - "sha256:892f933d339f068883b6fd5a459f03d85bfcb355e4981e146d2c7616c21fef71", - "sha256:c4014eb40e10f11f355ad4e3c2fb2c6c6d1919c73f3b5a433de4708202cade59" - ], - "index": "pypi", - "version": "==7.2.0" - } - } -} diff --git a/src/test/pipenv-test-app/Pipfile b/src/test/pipenv-test-app/Pipfile index f9c1ee0e..d6383329 100644 --- a/src/test/pipenv-test-app/Pipfile +++ b/src/test/pipenv-test-app/Pipfile @@ -5,7 +5,7 @@ name = "pypi" [packages] "e1839a8" = {path = ".", editable = true} -{% if spec.version in ["3.6", "3.8", "3.9", "3.10", "3.11"] %} +{% if spec.version in ["3.6", "3.8", "3.9"] %} requests = "==2.20.0" {% else %} requests = "==2.28.2" diff --git a/test/conftest.py b/test/conftest.py index bed51b9c..8af74506 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -112,7 +112,7 @@ def skip_helm_charts_tests(): - if VARS.VERSION in ("3.9-minimal", "3.11-minimal") or ( + if VARS.VERSION in ("3.9-minimal") or ( VARS.VERSION == "3.12-minimal" and VARS.OS == "rhel8" ): skip(f"Skipping Helm Charts tests for {VARS.VERSION} on {VARS.OS}.") diff --git a/test/test_ocp_helm_python_imagestreams.py b/test/test_ocp_helm_python_imagestreams.py index cf512b2d..9ca0424d 100644 --- a/test/test_ocp_helm_python_imagestreams.py +++ b/test/test_ocp_helm_python_imagestreams.py @@ -32,8 +32,6 @@ def teardown_method(self): ), ("3.12-ubi9", "registry.redhat.io/ubi9/python-312:latest"), ("3.12-ubi8", "registry.redhat.io/ubi8/python-312:latest"), - ("3.11-ubi9", "registry.redhat.io/ubi9/python-311:latest"), - ("3.11-ubi8", "registry.redhat.io/ubi8/python-311:latest"), ("3.9-ubi9", "registry.redhat.io/ubi9/python-39:latest"), ("3.6-ubi8", "registry.redhat.io/ubi8/python-36:latest"), ],