Pull changes from upstream for version 2.6

created from upstream commit: 2f676852fab45caf07c5958cf4b7fa6ffc2498d1
This commit is contained in:
Petr Kubat 2020-02-13 16:28:40 +01:00
commit a4e75f54ed
15 changed files with 359 additions and 111 deletions

View file

@ -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.
#
IMAGE_NAME=${IMAGE_NAME-centos/ruby-25-centos7-candidate}
IMAGE_NAME=${IMAGE_NAME-centos/ruby-26-centos7-candidate}
declare -a WEB_SERVERS=(db puma rack)
#declare -a WEB_SERVERS=(db)
@ -18,7 +18,7 @@ image_dir=$(readlink -zf ${test_dir}/..)
source "${test_dir}/test-lib.sh"
# Read exposed port from image meta data
test_port="$(docker inspect --format='{{range $key, $value := .ContainerConfig.ExposedPorts }}{{$key}}{{end}}' ${IMAGE_NAME} | sed 's/\/.*//')"
test_port="$(docker inspect --format='{{range $key, $value := .Config.ExposedPorts }}{{$key}}{{end}}' ${IMAGE_NAME} | sed 's/\/.*//')"
info() {
echo -e "\n\e[1m[INFO] $@...\e[0m\n"
@ -37,7 +37,7 @@ container_ip() {
}
run_s2i_build() {
ct_s2i_build_as_df file://${test_dir}/${1}-test-app ${IMAGE_NAME} ${IMAGE_NAME}-testapp ${s2i_args}
ct_s2i_build_as_df file://${test_dir}/${1}-test-app ${IMAGE_NAME} ${IMAGE_NAME}-testapp ${s2i_args} $(ct_build_s2i_npm_variables)
}
run_test_application() {

2
test/run-conu Executable file
View file

@ -0,0 +1,2 @@
#!/bin/bash
exec pytest -vv -k test_s2i

1
test/run-openshift Symbolic link
View file

@ -0,0 +1 @@
run-openshift-local-cluster

View file

@ -0,0 +1,30 @@
#!/bin/bash
#
# Test the Ruby S2I image in OpenShift (remote cluster)
#
# IMAGE_NAME specifies a name of the candidate image used for testing.
# The image has to be available before this script is executed.
# VERSION specifies the major version of the Ruby runtime in format of X.Y
# OS specifies RHEL version (e.g. OS=rhel7)
#
THISDIR=$(dirname ${BASH_SOURCE[0]})
source ${THISDIR}/test-lib-ruby.sh
set -eo nounset
trap ct_os_cleanup EXIT SIGINT
ct_os_check_compulsory_vars
oc status || false "It looks like oc is not properly logged in."
export CT_SKIP_NEW_PROJECT=true
export CT_SKIP_UPLOAD_IMAGE=true
export CT_NAMESPACE=openshift
test_ruby_integration ruby ${VERSION} "${IMAGE_NAME}"
OS_TESTSUITE_RESULT=0

1
test/test-lib-openshift.sh Symbolic link
View file

@ -0,0 +1 @@
../common/test-lib-openshift.sh

25
test/test-lib-ruby.sh Normal file
View file

@ -0,0 +1,25 @@
#!/bin/bash
#
# Functions for tests for the Ruby S2I image in OpenShift.
#
# IMAGE_NAME specifies a name of the candidate image used for testing.
# The image has to be available before this script is executed.
#
THISDIR=$(dirname ${BASH_SOURCE[0]})
source ${THISDIR}/test-lib.sh
source ${THISDIR}/test-lib-openshift.sh
function test_ruby_integration() {
local image_name=$1
local version=$2
local import_image=${3:-}
VERSION=$version ct_os_test_s2i_app "${image_name}" \
"https://github.com/sclorg/s2i-ruby-container.git" \
${version}/test/puma-test-app \
".*" \
8080 http 200 "" \
"${import_image}"
}

View file

@ -207,6 +207,38 @@ function ct_doc_content_old() {
: " Success!"
}
# full_ca_file_path
# Return string for full path to CA file
function full_ca_file_path()
{
echo "/etc/pki/ca-trust/source/anchors/RH-IT-Root-CA.crt"
}
# ct_mount_ca_file
# ------------------
# Check if /etc/pki/certs/RH-IT-Root-CA.crt file exists
# return mount string for containers or empty string
function ct_mount_ca_file()
{
# mount CA file only if NPM_REGISTRY variable is present.
local mount_parameter=""
if [ -n "$NPM_REGISTRY" ] && [ -f "$(full_ca_file_path)" ]; then
mount_parameter="-v $(full_ca_file_path):$(full_ca_file_path):Z"
fi
echo "$mount_parameter"
}
# ct_build_s2i_npm_variables URL_TO_NPM_JS_SERVER
# ------------------------------------------
# Function returns -e NPM_MIRROR and -v MOUNT_POINT_FOR_CAFILE
# or empty string
function ct_build_s2i_npm_variables()
{
npm_variables=""
if [ -n "$NPM_REGISTRY" ] && [ -f "$(full_ca_file_path)" ]; then
npm_variables="-e NPM_MIRROR=$NPM_REGISTRY $(ct_mount_ca_file)"
fi
echo "$npm_variables"
}
# ct_npm_works
# --------------------
@ -214,23 +246,39 @@ function ct_doc_content_old() {
function ct_npm_works() {
local tmpdir=$(mktemp -d)
: " Testing npm in the container image"
cid_file="${tmpdir}/cid"
docker run --rm ${IMAGE_NAME} /bin/bash -c "npm --version" >${tmpdir}/version
if [ $? -ne 0 ] ; then
echo "ERROR: 'npm --version' does not work inside the image ${IMAGE_NAME}." >&2
return 1
fi
docker run --rm ${IMAGE_NAME} /bin/bash -c "npm install jquery && test -f node_modules/jquery/src/jquery.js"
docker run -d $(ct_mount_ca_file) --rm --cidfile="$cid_file" ${IMAGE_NAME}-testapp
# Wait for the container to write it's CID file
ct_wait_for_cid "$cid_file" || return 1
docker exec $(cat "$cid_file") /bin/bash -c "npm --verbose install jquery && test -f node_modules/jquery/src/jquery.js" >${tmpdir}/jquery 2>&1
if [ $? -ne 0 ] ; then
echo "ERROR: npm could not install jquery inside the image ${IMAGE_NAME}." >&2
return 1
fi
if [ -n "$NPM_REGISTRY" ] && [ -f "$(full_ca_file_path)" ]; then
if ! grep -qo "$NPM_REGISTRY" "${tmpdir}/jquery"; then
echo "ERROR: Internal repository is NOT set. Even it is requested."
return 1
fi
fi
if [ -f "$cid_file" ]; then
docker stop $(cat "$cid_file")
rm "$cid_file"
fi
: " Success!"
}
# ct_path_append PATH_VARNAME DIRECTORY
# -------------------------------------
# Append DIRECTORY to VARIABLE of name PATH_VARNAME, the VARIABLE must consist
@ -372,7 +420,7 @@ ct_test_response() {
ct_registry_from_os() {
local registry=""
case $1 in
rhel7)
rhel*)
registry=registry.access.redhat.com
;;
*)
@ -443,7 +491,8 @@ ct_s2i_usage()
# Argument: APP_PATH - local path to the app sources to be used in the test
# Argument: SRC_IMAGE - image to be used as a base for the s2i build
# Argument: DST_IMAGE - image name to be used during the tagging of the s2i build result
# Argument: S2I_ARGS - Additional list of source-to-image arguments, currently only used to check for pull-policy=never.
# Argument: S2I_ARGS - Additional list of source-to-image arguments.
# Only used to check for pull-policy=never and environment variable definitions.
ct_s2i_build_as_df()
{
local app_path=$1; shift
@ -455,18 +504,50 @@ ct_s2i_build_as_df()
local user_id=
local df_name=
local tmpdir=
local incremental=false
local mount_options=""
# Run the entire thing inside a subshell so that we do not leak shell options outside of the function
(
# Error out if any part of the build fails
set -e
# Use /tmp to not pollute cwd
tmpdir=$(mktemp -d)
df_name=$(mktemp -p "$tmpdir" Dockerfile.XXXX)
pushd "$tmpdir"
cd "$tmpdir"
# Check if the image is available locally and try to pull it if it is not
docker images "$src_image" &>/dev/null || echo "$s2i_args" | grep -q "pull-policy=never" || docker pull "$src_image"
user_id=$(docker inspect -f "{{.ContainerConfig.User}}" "$src_image")
user=$(docker inspect -f "{{.Config.User}}" "$src_image")
# Default to root if no user is set by the image
user=${user:-0}
# run the user through the image in case it is non-numeric or does not exist
# NOTE: The '-eq' test is used to check if $user is numeric as it will fail if $user is not an integer
if ! [ "$user" -eq "$user" ] 2>/dev/null && ! user_id=$(docker run --rm "$src_image" bash -c "id -u $user 2>/dev/null"); then
echo "ERROR: id of user $user not found inside image $src_image."
echo "Terminating s2i build."
return 1
else
user_id=${user_id:-$user}
fi
echo "$s2i_args" | grep -q "\-\-incremental" && incremental=true
if $incremental; then
inc_tmp=$(mktemp -d --tmpdir incremental.XXXX)
setfacl -m "u:$user_id:rwx" "$inc_tmp"
# Check if the image exists, build should fail (for testing use case) if it does not
docker images "$dst_image" &>/dev/null || (echo "Image $dst_image not found."; false)
# Run the original image with a mounted in volume and get the artifacts out of it
cmd="if [ -s /usr/libexec/s2i/save-artifacts ]; then /usr/libexec/s2i/save-artifacts > \"$inc_tmp/artifacts.tar\"; else touch \"$inc_tmp/artifacts.tar\"; fi"
docker run --rm -v "$inc_tmp:$inc_tmp:Z" "$dst_image" bash -c "$cmd"
# Move the created content into the $tmpdir for the build to pick it up
mv "$inc_tmp/artifacts.tar" "$tmpdir/"
fi
# Strip file:// from APP_PATH and copy its contents into current context
mkdir -p "$local_app"
cp -r "${app_path/file:\/\//}/." "$local_app"
[ -d "$local_app/.s2i/bin/" ] && mv "$local_app/.s2i/bin" "$local_scripts"
# Create a Dockerfile named df_name and fill it with proper content
#FIXME: Some commands could be combined into a single layer but not sure if worth the trouble for testing purposes
cat <<EOF >"$df_name"
FROM $src_image
LABEL "io.openshift.s2i.build.image"="$src_image" \\
@ -477,13 +558,25 @@ EOF
[ -d "$local_scripts" ] && echo "COPY $local_scripts /tmp/scripts" >> "$df_name" &&
echo "RUN chown -R $user_id:0 /tmp/scripts" >>"$df_name"
echo "RUN chown -R $user_id:0 /tmp/src" >>"$df_name"
# Check for custom environment variables
# Check for custom environment variables inside .s2i/ folder
if [ -e "$local_app/.s2i/environment" ]; then
# Remove any comments and add the contents as ENV commands to the Dockerfile
sed '/^\s*#.*$/d' "$local_app/.s2i/environment" | while read -r line; do
echo "ENV $line" >>"$df_name"
done
fi
# Filter out env var definitions from $s2i_args and create Dockerfile ENV commands out of them
echo "$s2i_args" | grep -o -e '\(-e\|--env\)[[:space:]=]\S*=\S*' | sed -e 's/-e /ENV /' -e 's/--env[ =]/ENV /' >>"$df_name"
# Check if CA autority is present on host and add it into Dockerfile
[ -f "$(full_ca_file_path)" ] && echo "RUN cd /etc/pki/ca-trust/source/anchors && update-ca-trust extract" >>"$df_name"
# Add in artifacts if doing an incremental build
if $incremental; then
echo "RUN mkdir /tmp/artifacts" >>"$df_name"
echo "ADD artifacts.tar /tmp/artifacts" >>"$df_name"
echo "RUN chown -R $user_id:0 /tmp/artifacts" >>"$df_name"
fi
echo "USER $user_id" >>"$df_name"
# If exists, run the custom assemble script, else default to /usr/libexec/s2i/assemble
if [ -x "$local_scripts/assemble" ]; then
@ -497,7 +590,13 @@ EOF
else
echo "CMD /usr/libexec/s2i/run" >>"$df_name"
fi
# Check if -v parameter is present in s2i_args and add it into docker build command
mount_options=$(echo "$s2i_args" | grep -o -e '\(-v\)[[:space:]]\.*\S*' || true)
# Run the build and tag the result
docker build -f "$df_name" -t "$dst_image" .
popd
docker build $mount_options -f "$df_name" --no-cache=true -t "$dst_image" .
)
}
# vim: set tabstop=2:shiftwidth=2:expandtab:

83
test/test_s2i.py Normal file
View file

@ -0,0 +1,83 @@
#!/usr/bin/python3
import logging
import os
import time
from conu import DockerBackend, S2IDockerImage, Probe, DockerRunBuilder
import pytest
image_name = os.environ.get("IMAGE_NAME", "ruby")
test_dir = os.path.abspath(os.path.dirname(__file__))
puma_app_path = os.path.join(test_dir, "puma-test-app")
rack_app_path = os.path.join(test_dir, "rack-test-app")
app_paths = [
puma_app_path,
rack_app_path
]
backend = DockerBackend(logging_level=logging.DEBUG)
@pytest.fixture(scope="module", params=app_paths)
def app(request):
i = S2IDockerImage(image_name)
app_name = os.path.basename(request.param)
app = i.extend(request.param, app_name)
yield app
pass
app.rmi()
class TestSuite:
def test_s2i_apps(self, app):
c = app.run_via_binary()
try:
c.wait_for_port(8080)
assert c.is_port_open(8080)
response = c.http_request("/", port="8080")
assert response.ok
output = c.execute(["bash", "-c", "ruby --version"])[0]
expected = "ruby %s." % os.environ["VERSION"]
assert expected in output.decode("utf-8")
finally:
c.stop()
c.wait()
# debugging
print(list(c.logs()))
c.delete()
def test_invoking_container(self):
image = backend.ImageClass(image_name)
c = image.run_via_binary(DockerRunBuilder(command=["bash", "-c", "ruby --version"]))
try:
c.wait()
logs = list(c.logs())[0].decode("utf-8")
finally:
c.stop()
c.wait()
c.delete()
assert "ruby " in logs
if os.environ.get("VERSION", None):
assert os.environ["VERSION"] in logs
def test_usage(self):
i = S2IDockerImage(image_name)
c = i.run_via_binary()
def logs_received():
return len(list(c.logs())) > 0
try:
c.wait()
# even after waiting there is still a race in journal logging driver
Probe(timeout=10, pause=0.05, count=20, fnc=logs_received).run()
logs = [x.decode("utf-8") for x in c.logs()]
logs = "\n".join(logs).strip()
usage = i.usage()
# FIXME: workaround: `docker logs` can't handle logs like these: '\n\n\n'
assert logs.replace("\n", "") == usage.replace("\n", "")
finally:
c.delete()