Update from upstream github repo
- pipenv is locked to older stable version - ENV for micropipenv - no python-virtualenv package - updated documentation
This commit is contained in:
parent
584be66e16
commit
b0910418b6
15 changed files with 308 additions and 17 deletions
|
|
@ -38,9 +38,9 @@ LABEL summary="$SUMMARY" \
|
|||
usage="s2i build https://github.com/sclorg/s2i-python-container.git --context-dir=3.8/test/setup-test-app/ $FGC/$NAME python-sample-app" \
|
||||
maintainer="SoftwareCollections.org <sclorg@redhat.com>"
|
||||
|
||||
RUN INSTALL_PKGS="python3 python3-devel python3-setuptools python3-pip python3-virtualenv \
|
||||
nss_wrapper httpd httpd-devel atlas-devel gcc-gfortran \
|
||||
libffi-devel libtool-ltdl enchant redhat-rpm-config" && \
|
||||
RUN INSTALL_PKGS="python3 python3-devel python3-setuptools python3-pip nss_wrapper \
|
||||
httpd httpd-devel atlas-devel gcc-gfortran libffi-devel \
|
||||
libtool-ltdl enchant redhat-rpm-config" && \
|
||||
dnf -y --setopt=tsflags=nodocs install $INSTALL_PKGS && \
|
||||
rpm -V $INSTALL_PKGS && \
|
||||
dnf -y clean all --enablerepo='*'
|
||||
|
|
|
|||
12
README.md
12
README.md
|
|
@ -32,7 +32,7 @@ the nodejs itself is included just to make the npm work.
|
|||
Usage
|
||||
---------------------
|
||||
|
||||
For this, we will assume that you are using the `rhscl/python-38-rhel7 image`, available via `python:3.8` imagestream tag in Openshift.
|
||||
For this, we will assume that you are using the supported image, available via `python:3.8` imagestream tag in Openshift.
|
||||
Building a simple [python-sample-app](https://github.com/sclorg/s2i-python-container/tree/master/3.8/test/setup-test-app) application
|
||||
in Openshift can be achieved with the following step:
|
||||
|
||||
|
|
@ -43,9 +43,11 @@ in Openshift can be achieved with the following step:
|
|||
The same application can also be built using the standalone [S2I](https://github.com/openshift/source-to-image) application on systems that have it available:
|
||||
|
||||
```
|
||||
$ s2i build https://github.com/sclorg/s2i-python-container.git --context-dir=3.8/test/setup-test-app/ rhscl/python-38-rhel7 python-sample-app
|
||||
$ s2i build https://github.com/sclorg/s2i-python-container.git --context-dir=3.8/test/setup-test-app/ <image_name> python-sample-app
|
||||
```
|
||||
|
||||
Where `<image_name>` is the s2i-python image you [downloaded from RHEL, Centos or Fedora registry](../README.md#Download) or [built](../README.md#Build) from these sources. For example ubi8/python-36, centos/python-36-centos7 or f31/python3.
|
||||
|
||||
**Accessing the application:**
|
||||
```
|
||||
$ curl 127.0.0.1:8080
|
||||
|
|
@ -125,6 +127,12 @@ file inside your source code repository.
|
|||
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.
|
||||
* **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**
|
||||
|
||||
|
|
|
|||
|
|
@ -14,22 +14,30 @@ function virtualenv_bin() {
|
|||
python3.8 -m venv $1
|
||||
}
|
||||
|
||||
# Install pipenv to the separate virtualenv to isolate it
|
||||
# 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_pipenv() {
|
||||
echo "---> Installing pipenv packaging tool ..."
|
||||
VENV_DIR=$HOME/.local/venvs/pipenv
|
||||
function install_tool() {
|
||||
echo "---> Installing $1 packaging tool ..."
|
||||
VENV_DIR=$HOME/.local/venvs/$1
|
||||
virtualenv_bin "$VENV_DIR"
|
||||
$VENV_DIR/bin/pip --isolated install -U pipenv
|
||||
$VENV_DIR/bin/pip --isolated install -U $1$2 # Combines package name with [extras] if [extras] is defined as $2
|
||||
mkdir -p $HOME/.local/bin
|
||||
ln -s $VENV_DIR/bin/pipenv $HOME/.local/bin/pipenv
|
||||
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"
|
||||
|
|
@ -50,7 +58,7 @@ if [[ ! -z "$UPGRADE_PIP_TO_LATEST" ]]; then
|
|||
fi
|
||||
|
||||
if [[ ! -z "$ENABLE_PIPENV" ]]; then
|
||||
install_pipenv
|
||||
install_tool "pipenv" "==2018.11.26"
|
||||
echo "---> Installing dependencies via pipenv ..."
|
||||
if [[ -f Pipfile ]]; then
|
||||
pipenv install --deploy
|
||||
|
|
@ -58,6 +66,11 @@ if [[ ! -z "$ENABLE_PIPENV" ]]; 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
|
||||
|
|
|
|||
2
test/micropipenv-requirements-test-app/.s2i/environment
Normal file
2
test/micropipenv-requirements-test-app/.s2i/environment
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
ENABLE_MICROPIPENV=true
|
||||
DISABLE_SETUP_PY_PROCESSING=true
|
||||
14
test/micropipenv-requirements-test-app/app.py
Normal file
14
test/micropipenv-requirements-test-app/app.py
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import os
|
||||
import mod_wsgi.server
|
||||
|
||||
mod_wsgi.server.start(
|
||||
'--log-to-terminal',
|
||||
'--port', '8080',
|
||||
'--trust-proxy-header', 'X-Forwarded-For',
|
||||
'--trust-proxy-header', 'X-Forwarded-Port',
|
||||
'--trust-proxy-header', 'X-Forwarded-Proto',
|
||||
'--processes', os.environ.get('MOD_WSGI_PROCESSES', '1'),
|
||||
'--threads', os.environ.get('MOD_WSGI_THREADS', '5'),
|
||||
'--application-type', 'module',
|
||||
'--entry-point', 'wsgi'
|
||||
)
|
||||
2
test/micropipenv-requirements-test-app/requirements.txt
Normal file
2
test/micropipenv-requirements-test-app/requirements.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
mod_wsgi
|
||||
Flask
|
||||
9
test/micropipenv-requirements-test-app/wsgi.py
Normal file
9
test/micropipenv-requirements-test-app/wsgi.py
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
from flask import Flask
|
||||
application = Flask(__name__)
|
||||
|
||||
@application.route('/')
|
||||
def hello():
|
||||
return b'Hello World from mod_wsgi hosted WSGI application!'
|
||||
|
||||
if __name__ == '__main__':
|
||||
application.run()
|
||||
57
test/micropipenv-test-app/.gitignore
vendored
Normal file
57
test/micropipenv-test-app/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
# 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/
|
||||
2
test/micropipenv-test-app/.s2i/environment
Normal file
2
test/micropipenv-test-app/.s2i/environment
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
ENABLE_MICROPIPENV=true
|
||||
DISABLE_SETUP_PY_PROCESSING=true
|
||||
14
test/micropipenv-test-app/Pipfile
Normal file
14
test/micropipenv-test-app/Pipfile
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
[[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.8"
|
||||
133
test/micropipenv-test-app/Pipfile.lock
generated
Normal file
133
test/micropipenv-test-app/Pipfile.lock
generated
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "f1d3ff05e8c9143e751780c871a656ef8794c15cf6e8ef08cfa211ad25a24320"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.8"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.python.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:017c25db2a153ce562900032d5bc68e9f191e44e9a0f762f373977de9df1fbb3",
|
||||
"sha256:25b64c7da4cd7479594d035c08c2d809eb4aab3a26e5a990ea98cc450c320f1f"
|
||||
],
|
||||
"version": "==2019.11.28"
|
||||
},
|
||||
"chardet": {
|
||||
"hashes": [
|
||||
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
|
||||
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
|
||||
],
|
||||
"version": "==3.0.4"
|
||||
},
|
||||
"e1839a8": {
|
||||
"editable": true,
|
||||
"path": "."
|
||||
},
|
||||
"gunicorn": {
|
||||
"hashes": [
|
||||
"sha256:1904bb2b8a43658807108d59c3f3d56c2b6121a701161de0ddf9ad140073c626",
|
||||
"sha256:cd4a810dd51bf497552cf3f863b575dabd73d6ad6a91075b65936b151cbf4f9c"
|
||||
],
|
||||
"version": "==20.0.4"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e",
|
||||
"sha256:684a38a6f903c1d71d6d5fac066b58d7768af4de2b832e426ec79c30daa94a16"
|
||||
],
|
||||
"version": "==2.7"
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
"sha256:99dcfdaaeb17caf6e526f32b6a7b780461512ab3f1d992187801694cba42770c",
|
||||
"sha256:a84b8c9ab6239b578f22d1c21d51b696dcfe004032bb80ea832398d6909d7279"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.20.0"
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:2393a695cd12afedd0dcb26fe5d50d0cf248e5a66f75dbd89a3d4eb333a61af4",
|
||||
"sha256:a637e5fae88995b256e3409dc4d52c2e2e0ba32c42a6365fee8bbd2238de3cfb"
|
||||
],
|
||||
"version": "==1.24.3"
|
||||
}
|
||||
},
|
||||
"develop": {
|
||||
"attrs": {
|
||||
"hashes": [
|
||||
"sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c",
|
||||
"sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"
|
||||
],
|
||||
"version": "==19.3.0"
|
||||
},
|
||||
"more-itertools": {
|
||||
"hashes": [
|
||||
"sha256:b84b238cce0d9adad5ed87e745778d20a3f8487d0f0cb8b8a586816c7496458d",
|
||||
"sha256:c833ef592a0324bcc6a60e48440da07645063c453880c9477ceb22490aec1564"
|
||||
],
|
||||
"version": "==8.0.2"
|
||||
},
|
||||
"packaging": {
|
||||
"hashes": [
|
||||
"sha256:28b924174df7a2fa32c1953825ff29c61e2f5e082343165438812f00d3a7fc47",
|
||||
"sha256:d9551545c6d761f3def1677baf08ab2a3ca17c56879e70fecba2fc4dde4ed108"
|
||||
],
|
||||
"version": "==19.2"
|
||||
},
|
||||
"pluggy": {
|
||||
"hashes": [
|
||||
"sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0",
|
||||
"sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"
|
||||
],
|
||||
"version": "==0.13.1"
|
||||
},
|
||||
"py": {
|
||||
"hashes": [
|
||||
"sha256:64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa",
|
||||
"sha256:dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53"
|
||||
],
|
||||
"version": "==1.8.0"
|
||||
},
|
||||
"pyparsing": {
|
||||
"hashes": [
|
||||
"sha256:20f995ecd72f2a1f4bf6b072b63b22e2eb457836601e76d6e5dfcd75436acc1f",
|
||||
"sha256:4ca62001be367f01bd3e92ecbb79070272a9d4964dce6a48a82ff0b8bc7e683a"
|
||||
],
|
||||
"version": "==2.4.5"
|
||||
},
|
||||
"pytest": {
|
||||
"hashes": [
|
||||
"sha256:63344a2e3bce2e4d522fd62b4fdebb647c019f1f9e4ca075debbd13219db4418",
|
||||
"sha256:f67403f33b2b1d25a6756184077394167fe5e2f9d8bdaab30707d19ccec35427"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==5.3.1"
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd",
|
||||
"sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"
|
||||
],
|
||||
"version": "==1.13.0"
|
||||
},
|
||||
"wcwidth": {
|
||||
"hashes": [
|
||||
"sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e",
|
||||
"sha256:f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c"
|
||||
],
|
||||
"version": "==0.1.7"
|
||||
}
|
||||
}
|
||||
}
|
||||
10
test/micropipenv-test-app/setup.py
Normal file
10
test/micropipenv-test-app/setup.py
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
from setuptools import setup, find_packages
|
||||
|
||||
|
||||
setup (
|
||||
name = "testapp",
|
||||
version = "0.1",
|
||||
description = "Example application to be deployed.",
|
||||
packages = find_packages(),
|
||||
install_requires = ["gunicorn"],
|
||||
)
|
||||
7
test/micropipenv-test-app/testapp.py
Normal file
7
test/micropipenv-test-app/testapp.py
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import requests
|
||||
|
||||
|
||||
def application(environ, start_response):
|
||||
start_response('200 OK', [('Content-Type', 'text/plain')])
|
||||
assert requests.__version__ == '2.20.0'
|
||||
return [b"Hello from gunicorn WSGI application!"]
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
ENABLE_PIPENV=true
|
||||
ENABLE_MICROPIPENV=true
|
||||
28
test/run
28
test/run
|
|
@ -6,7 +6,7 @@
|
|||
# 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 WEB_APPS=({standalone,setup,setup-requirements,django,numpy,app-home,npm-virtualenv-uwsgi,locale,mod-wsgi,pipenv}-test-app)
|
||||
declare -a WEB_APPS=({standalone,setup,setup-requirements,django,numpy,app-home,npm-virtualenv-uwsgi,locale,mod-wsgi,pipenv,pipenv-and-micropipenv-should-fail,micropipenv,micropipenv-requirements}-test-app)
|
||||
|
||||
# TODO: Make command compatible for Mac users
|
||||
test_dir="$(readlink -zf $(dirname "${BASH_SOURCE[0]}"))"
|
||||
|
|
@ -36,6 +36,7 @@ container_exists() {
|
|||
image_exists $(cat $cid_file)
|
||||
}
|
||||
|
||||
|
||||
container_ip() {
|
||||
docker inspect --format="{{ .NetworkSettings.IPAddress }}" $(cat $cid_file)
|
||||
}
|
||||
|
|
@ -82,11 +83,18 @@ cleanup() {
|
|||
}
|
||||
|
||||
check_result() {
|
||||
# positive test & non-zero exit status = ERROR
|
||||
# negative test & zero exit status = ERROR
|
||||
local result="$1"
|
||||
if [[ "$result" != "0" ]]; then
|
||||
info "TEST FAILED (${result})"
|
||||
local test=${2:-positive} # if not defined, we expect possitive test type (zero exit code)
|
||||
if [[ "$type" == "positive" && "$result" != "0" ]]; then
|
||||
info "TEST FAILED (${type}), EXPECTED:0 GOT:${result}"
|
||||
cleanup
|
||||
exit $result
|
||||
elif [[ "$type" == "negative" && "$result" == "0" ]]; then
|
||||
info "TEST FAILED (${type}), EXPECTED: non-zero GOT:${result}"
|
||||
cleanup
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
|
@ -189,10 +197,20 @@ check_result $?
|
|||
test_docker_run_usage
|
||||
check_result $?
|
||||
|
||||
for app in ${WEB_APPS[@]}; do
|
||||
# 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
|
||||
prepare ${app}
|
||||
run_s2i_build ${app}
|
||||
check_result $?
|
||||
RESULT=$?
|
||||
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"
|
||||
continue
|
||||
else
|
||||
check_result $RESULT
|
||||
fi
|
||||
|
||||
# test application with default user
|
||||
test_application
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue