Update from the upstream Github repository

This commit is contained in:
Lumir Balhar 2021-04-07 08:44:42 +02:00
commit fdf8f9b035
12 changed files with 236 additions and 68 deletions

View file

@ -74,7 +74,7 @@ To use the Python image in a Dockerfile, follow these steps:
#### 1. Pull a base builder image to build on
```
podman pull
podman pull registry.fedoraproject.org/f33/python3
```
#### 2. Pull and application code
@ -105,18 +105,44 @@ 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
FROM registry.fedoraproject.org/f33/python3
# 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 chown -R 1001:0 /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.fedoraproject.org/f33/python3
# 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
```

View file

@ -6,13 +6,13 @@ NAMESPACE=centos
cat <<EOF
This is a S2I python-3.9 ${DISTRO} base image:
To use it, install S2I: https://github.com/openshift/source-to-image
Sample invocation:
s2i build https://github.com/sclorg/s2i-python-container.git --context-dir=3.9/test/setup-test-app/ ${NAMESPACE}/python-39-${DISTRO}7 python-sample-app
There are multiple ways how to run the image, see documentation at:
https://github.com/sclorg/s2i-python-container/blob/master/3.9/README.md
To use it in Openshift, run:
oc new-app python:3.9~https://github.com/sclorg/s2i-python-container.git --context-dir=3.9/test/setup-test-app/
You can then run the resulting image via:
podman run -p 8080:8080 python-sample-app
oc get pods
oc exec <pod> -- curl 127.0.0.1:8080
EOF

View file

@ -1,5 +1,27 @@
#!/bin/env python3
# MIT License
#
# Copyright (c) 2018-2019 Red Hat, Inc.
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import sys
import json
import logging

View file

@ -4,7 +4,7 @@ FROM #IMAGE_NAME# # Replaced by sed in tests, see test_from_dockerfile in test/r
# and set permissions so that the container runs without root access
USER 0
ADD app-src /tmp/src
RUN chown -R 1001:0 /tmp/src
RUN /usr/bin/fix-permissions /tmp/src
USER 1001
# Install the dependencies

View file

@ -0,0 +1,16 @@
FROM #IMAGE_NAME# # Replaced by sed in tests, see test_from_dockerfile in test/run
# 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

View file

@ -142,7 +142,7 @@
},
"from": {
"kind": "DockerImage",
"name": "docker.io/centos/python-27-centos7:latest"
"name": "quay.io/centos7/python-27-centos7:latest"
},
"referencePolicy": {
"type": "Local"

View file

@ -13,7 +13,7 @@ packages=("pip" "setuptools" "wheel")
for pkg in ${packages[@]}; do
# grep returns exit code 1 if the output contains only one line starting
# with "Requirement already …" which means that the package is updated
python -m pip install -U --no-deps --no-python-version-warning $pkg 2>&1 | grep -v "^Requirement already up-to-date: "
python -m pip install -U --no-deps --no-python-version-warning $pkg 2>&1 | grep -Ev "^Requirement already (up-to-date|satisfied): "
if [ $? -eq 0 ]; then
echo "ERROR: Failed to upgrade '$pkg' to the latest version."
exit 1

150
test/run
View file

@ -12,6 +12,22 @@ declare -a WEB_APPS=({standalone,setup,setup-requirements,django,numpy,app-home,
test_dir="$(readlink -zf $(dirname "${BASH_SOURCE[0]}"))"
image_dir=$(readlink -zf ${test_dir}/..)
test_short_summary=''
TESTSUITE_RESULT=0
TEST_LIST="\
test_s2i_usage
test_docker_run_usage
test_application
test_application_with_user
test_application_enable_init_wrapper
"
TEST_VAR_DOCKER="\
test_scl_variables_in_dockerfile
test_from_dockerfile
"
if [[ -z $VERSION ]]; then
echo "ERROR: The VERSION variable must be set."
exit 1
@ -82,7 +98,7 @@ cleanup() {
rm -rf ${test_dir}/${1}/.git
}
check_result() {
check_type() {
# positive test & non-zero exit status = ERROR
# negative test & zero exit status = ERROR
local result="$1"
@ -90,12 +106,22 @@ check_result() {
if [[ "$type" == "positive" && "$result" != "0" ]]; then
info "TEST FAILED (${type}), EXPECTED:0 GOT:${result}"
cleanup
exit $result
return $result
elif [[ "$type" == "negative" && "$result" == "0" ]]; then
info "TEST FAILED (${type}), EXPECTED: non-zero GOT:${result}"
cleanup
exit 1
return 1
fi
}
check_result() {
# Function sets if test suite failed or not
# If return value is not 0 then mark test case as TESTCASE_RESULT=1
local result="$1"
if [[ "$result" != "0" ]]; then
TESTCASE_RESULT=1
fi
return $result
}
wait_for_cid() {
@ -189,65 +215,113 @@ test_application() {
test_from_dockerfile(){
info "Test from Dockerfile"
# The latest LTS release of Django does not work on RHEL 7 (due to an old version of SQLite),
# and no longer supports Python 2. So on all CentOS/RHEL 7 images and all Python 2 images,
# we're using the old Django LTS version 1.11.x from the main git branch of the django-ex project.
# In all other cases we're using the newer Django LTS version 2.2.x from the corresponding git branch.
if [[ ${VERSION} == "2.7" ]] || [[ ${IMAGE_NAME} =~ "centos7" ]] || [[ ${IMAGE_NAME} =~ "rhel7" ]] || [[ ${IMAGE_NAME} =~ "ubi7" ]]; then
django_example_repo_url="https://github.com/sclorg/django-ex.git"
else
django_example_repo_url="https://github.com/sclorg/django-ex.git@2.2.x"
fi
sed "s@#IMAGE_NAME#@${IMAGE_NAME}@" $test_dir/from-dockerfile/Dockerfile.tpl > $test_dir/from-dockerfile/Dockerfile
ct_test_app_dockerfile $test_dir/from-dockerfile/Dockerfile 'https://github.com/sclorg/django-ex.git' 'Welcome to your Django application on OpenShift' app-src
ct_test_app_dockerfile $test_dir/from-dockerfile/Dockerfile $django_example_repo_url 'Welcome to your Django application on OpenShift' app-src
check_result $?
info "Test from Dockerfile with no s2i scripts used"
sed "s@#IMAGE_NAME#@${IMAGE_NAME}@" $test_dir/from-dockerfile/Dockerfile_no_s2i.tpl > $test_dir/from-dockerfile/Dockerfile
ct_test_app_dockerfile $test_dir/from-dockerfile/Dockerfile $django_example_repo_url 'Welcome to your Django application on OpenShift' app-src
check_result $?
}
# Since we built the candidate image locally, we don't want S2I attempt to pull
# it from Docker hub
s2i_args="--pull-policy=never"
test_application_with_user() {
# test application with random user
CONTAINER_ARGS="--user 12345" test_application
# Verify the 'usage' script is working properly when running the base image with 's2i usage ...'
test_s2i_usage
check_result $?
}
# Verify the 'usage' script is working properly when running the base image with 'docker run ...'
test_docker_run_usage
check_result $?
test_application_enable_init_wrapper() {
# test application with init wrapper
CONTAINER_ARGS="-e ENABLE_INIT_WRAPPER=true" test_application
}
test_scl_variables_in_dockerfile() {
if [ "$OS" == "rhel7" ] || [ "$OS" == "centos7" ]; then
TESTCASE_RESULT=0
# autocleanup only enabled here as only the following tests so far use it
CID_FILE_DIR=$(mktemp -d)
ct_enable_cleanup
info "Testing variable presence during \`docker exec\`"
ct_check_exec_env_vars
check_result $?
info "Checking if all scl variables are defined in Dockerfile"
ct_check_scl_enable_vars
check_result $?
fi
}
function run_all_tests() {
local APP_NAME=${1:-undefined}
for test_case in $TEST_SET; do
info "Running test $test_case ... "
TESTCASE_RESULT=0
$test_case
local test_msg
if [ $TESTCASE_RESULT -eq 0 ]; then
test_msg="[PASSED]"
else
test_msg="[FAILED]"
TESTSUITE_RESULT=1
fi
test "$APP_NAME" == "undefined" && msg_app="" || msg_app="'$APP_NAME'"
printf -v test_short_summary "%s %s for %s %s\n" "${test_short_summary}" "${test_msg}" "${msg_app}" "$test_case"
[ -n "${FAIL_QUICKLY:-}" ] && {
cleanup "${APP_NAME}"
return 1
}
done;
}
# 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"
prepare ${app}
run_s2i_build ${app}
RESULT=$?
msg_run_s2i_build="'${app}' run_s2i_build"
if [[ "$app" == *"-should-fail-"* ]]; then
# Tests with '-should-fail-' in their name should fail during a build, expecting non-zero exit status
check_result $RESULT "negative"
check_type $RESULT "negative"
test "$?" == "0" && test_msg="[PASSED]" || test_msg="[FAILED]"
printf -v test_short_summary "%s %s for %s\n" "${test_short_summary}" "$test_msg" "$msg_run_s2i_build"
continue
else
check_result $RESULT
check_type $RESULT
test "$?" != "0" && test_msg="[FAILED]" || test_msg="[PASSED]"
printf -v test_short_summary "%s %s for %s\n" "${test_short_summary}" "$test_msg" "$msg_run_s2i_build"
fi
echo ""
TEST_SET=${TESTS:-$TEST_LIST} run_all_tests "${app}"
# test application with default user
test_application
# test application with random user
CONTAINER_ARGS="--user 12345" test_application
# test application with init wrapper
CONTAINER_ARGS="-e ENABLE_INIT_WRAPPER=true" test_application
info "All tests for the ${app} finished successfully."
cleanup ${app}
done
if [ "$OS" == "rhel7" ] || [ "$OS" == "centos7" ]; then
# autocleanup only enabled here as only the following tests so far use it
CID_FILE_DIR=$(mktemp -d)
ct_enable_cleanup
TEST_SET=${TESTS:-$TEST_VAR_DOCKER} run_all_tests
info "Testing variable presence during \`docker exec\`"
ct_check_exec_env_vars
check_result $?
echo "$test_short_summary"
info "Checking if all scl variables are defined in Dockerfile"
ct_check_scl_enable_vars
check_result $?
if [ $TESTSUITE_RESULT -eq 0 ] ; then
echo "Tests for ${IMAGE_NAME} succeeded."
else
echo "Tests for ${IMAGE_NAME} failed."
fi
test_from_dockerfile
info "All tests finished successfully."
exit $TESTSUITE_RESULT

View file

@ -46,8 +46,8 @@ for template in $EPHEMERAL_TEMPLATES; do
"$template" \
python \
'Welcome to your Django application on OpenShift' \
8080 http 200 "-p SOURCE_REPOSITORY_REF=master -p PYTHON_VERSION=${VERSION} -p POSTGRESQL_VERSION=9.6 -p NAME=python-testing" \
"centos/postgresql-96-centos7|postgresql:9.6"
8080 http 200 "-p SOURCE_REPOSITORY_REF=master -p PYTHON_VERSION=${VERSION} -p POSTGRESQL_VERSION=10 -p NAME=python-testing" \
"quay.io/centos7/postgresql-10-centos7|postgresql:10"
done
# Check the imagestream

View file

@ -617,20 +617,21 @@ function ct_os_test_s2i_app_func() {
ct_os_new_project
namespace=${CT_NAMESPACE:-"$(oc project -q)"}
local image_tagged="${image_name_no_namespace%:*}:${VERSION}"
if [ "${CT_EXTERNAL_REGISTRY:-false}" == 'true' ] ; then
ct_os_import_image_ocp4 "${image_name}" "${image_name_no_namespace}"
ct_os_import_image_ocp4 "${image_name}" "${image_tagged}"
else
# Create a specific imagestream tag for the image so that oc cannot use anything else
if [ "${CT_SKIP_UPLOAD_IMAGE:-false}" == 'true' ] ; then
echo "Importing image ${image_name} as ${namespace}/${image_name_no_namespace}"
echo "Importing image ${image_name} as ${namespace}/${image_tagged}"
# Use --reference-policy=local to pull remote image content to the cluster
# Works around the issue of builder pods not having access to registry.redhat.io
oc tag --source=docker "${image_name}" "${namespace}/${image_name_no_namespace}" --insecure=true --reference-policy=local
ct_os_wait_stream_ready "${image_name_no_namespace}" "${namespace}"
oc tag --source=docker "${image_name}" "${namespace}/${image_tagged}" --insecure=true --reference-policy=local
ct_os_wait_stream_ready "${image_tagged}" "${namespace}"
else
echo "Uploading image ${image_name} as ${image_name_no_namespace}"
ct_os_upload_image "${image_name}" "${image_name_no_namespace}"
echo "Uploading image ${image_name} as ${image_tagged}"
ct_os_upload_image "${image_name}" "${image_tagged}"
fi
fi
@ -642,7 +643,7 @@ function ct_os_test_s2i_app_func() {
fi
# shellcheck disable=SC2086
ct_os_deploy_s2i_image "${image_name_no_namespace}" "${app_param}" \
ct_os_deploy_s2i_image "${image_tagged}" "${app_param}" \
--context-dir="${context_dir}" \
--name "${service_name}" \
${oc_args}
@ -793,6 +794,8 @@ function ct_os_test_template_app_func() {
local local_template
local_template=$(ct_obtain_input "${template}" 2>/dev/null || echo "--template=${template}")
echo "Creating a new-app with name ${name_in_template} in namespace ${namespace} with args ${oc_args}."
# shellcheck disable=SC2086
oc new-app "${local_template}" \
--name "${name_in_template}" \
@ -928,7 +931,7 @@ ct_os_test_image_update() {
function ct_os_deploy_cmd_image() {
local image_name=${1}
oc get pod command-app &>/dev/null && echo "command POD already running" && return 0
echo "command POD not running yet, will start one called command-app"
echo "command POD not running yet, will start one called command-app ${image_name}"
oc create -f - <<EOF
apiVersion: v1
kind: Pod
@ -946,6 +949,8 @@ EOF
SECONDS=0
echo -n "Waiting for command POD ."
while [ $SECONDS -lt 180 ] ; do
# Let's show status of all pods. Not only command-container for tracking issues
oc get pods
# shellcheck disable=SC2016
sout="$(ct_os_cmd_image_run 'echo $((11*11))' 2>/dev/null)"
# shellcheck disable=SC2015
@ -992,7 +997,7 @@ ct_os_test_response_internal() {
local status
local response_code
local response_file
local util_image_name='python:3.6'
local util_image_name='ubi7/ubi'
response_file=$(mktemp /tmp/ct_test_response_XXXXXX)
ct_os_deploy_cmd_image "${util_image_name}"
@ -1231,16 +1236,30 @@ function ct_os_test_image_stream_quickstart() {
local local_template_file
echo "Running image stream test for stream ${image_stream_file} and quickstart template ${template_file}"
echo "Image name is ${IMAGE_NAME}"
# shellcheck disable=SC2119
ct_os_new_project
local_image_stream_file=$(ct_obtain_input "${image_stream_file}")
local_template_file=$(ct_obtain_input "${template_file}")
oc create -f "${local_image_stream_file}"
# ct_os_test_template_app creates a new project, but we already need
# it before for the image stream import, so tell it to skip this time
namespace=${CT_NAMESPACE:-"$(oc project -q)"}
# Add namespace into openshift arguments
if [[ $oc_args != *"NAMESPACE"* ]]; then
oc_args="${oc_args} -p NAMESPACE=${namespace}"
fi
oc create -f "${local_image_stream_file}"
# In case we are testing on OpenShift 4 export variable for mirror image
# which means, that image is going to be mirrored from an internal registry into OpenShift 4
if [ "${CT_EXTERNAL_REGISTRY:-false}" == 'true' ]; then
export CT_MIRROR_IMAGE=true
fi
# ct_os_test_template_app creates a new project, but we already need
# it before for the image stream import, so tell it to skip this time
CT_SKIP_NEW_PROJECT=true \
ct_os_test_template_app "${image_name}" \
"${local_template_file}" \

View file

@ -23,8 +23,8 @@ function test_python_imagestream() {
"${IMAGE_NAME}" \
'python' \
'Welcome to your Django application on OpenShift' \
8080 http 200 "-p SOURCE_REPOSITORY_REF=master -p PYTHON_VERSION=${VERSION} -p POSTGRESQL_VERSION=9.6 -p NAME=python-testing" \
"centos/postgresql-96-centos7|postgresql:9.6"
8080 http 200 "-p SOURCE_REPOSITORY_REF=master -p PYTHON_VERSION=${VERSION} -p POSTGRESQL_VERSION=10 -p NAME=python-testing" \
"quay.io/centos7/postgresql-10-centos7|postgresql:10"
}
# vim: set tabstop=2:shiftwidth=2:expandtab:

View file

@ -84,11 +84,12 @@ function ct_check_envs_set {
if [ -n "${filtered_envs##${env_format//VALUE/$value}}" ]; then
echo " Value $value is missing from variable $var_name"
echo "$filtered_envs"
IFS=$old_IFS
return 1
fi
done
IFS=$old_IFS
done <<< "$(echo "$loop_envs" | grep "$env_filter" | grep -v "^PWD=")"
IFS=$old_IFS
}
# ct_get_cid [name]
@ -817,7 +818,7 @@ ct_show_resources()
echo "Memory:"
free -h
echo "Storage:"
df -h
df -h || :
echo "CPU"
lscpu
}
@ -826,7 +827,7 @@ ct_show_resources()
# -----------------------------
# Argument: dockerfile - path to a Dockerfile that will be used for building an image
# (must work with an application directory called 'app-src')
# Argument: app_url - git URI with a testing application
# Argument: app_url - git URI with a testing application, supports "@" to indicate a different branch
# Argument: body_regexp - PCRE regular expression that must match the response body
# Argument: app_dir - name of the application directory that is used in the Dockerfile
# Argument: port - Optional port number (default: 8080)
@ -864,7 +865,17 @@ ct_test_app_dockerfile() {
echo "Using this Dockerfile:"
cat Dockerfile
if ! git clone "${app_url}" "${app_dir}" ; then
# If app_url contains @, the string after @ is considered
# as a name of a branch to clone instead of the main/master branch
IFS='@' read -ra git_url_parts <<< "${app_url}"
if [ -n "${git_url_parts[1]}" ]; then
git_clone_cmd="git clone --branch ${git_url_parts[1]} ${git_url_parts[0]} ${app_dir}"
else
git_clone_cmd="git clone ${app_url} ${app_dir}"
fi
if ! $git_clone_cmd ; then
echo "ERROR: Git repository ${app_url} cannot be cloned into ${app_dir}."
echo "Terminating the Dockerfile build."
return 1