diff --git a/.gitignore b/.gitignore deleted file mode 100644 index e69de29..0000000 diff --git a/.s2i/bin/assemble b/.s2i/bin/assemble deleted file mode 100755 index 8a7ad10..0000000 --- a/.s2i/bin/assemble +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/bash -e -# -# S2I assemble script for the 'nodejs-fedora' image. -# The 'assemble' script builds your application source so that it is ready to run. -# -# For more information refer to the documentation: -# https://github.com/openshift/source-to-image/blob/master/docs/builder_image.md -# - -if [[ "$1" == "-h" ]]; then - # If the 'nodejs' assemble script is executed with '-h' flag, - # print the usage. - exec /usr/local/s2i/usage -fi - -echo "---> Installing application source..." -mv /tmp/src/* ./ - -if [ ! -z $HTTP_PROXY ]; then - echo "---> Setting npm http proxy to $HTTP_PROXY" - npm config set proxy $HTTP_PROXY -fi - -if [ ! -z $http_proxy ]; then - echo "---> Setting npm http proxy to $http_proxy" - npm config set proxy $http_proxy -fi - -if [ ! -z $HTTPS_PROXY ]; then - echo "---> Setting npm https proxy to $HTTPS_PROXY" - npm config set https-proxy $HTTPS_PROXY -fi - -if [ ! -z $https_proxy ]; then - echo "---> Setting npm https proxy to $https_proxy" - npm config set https-proxy $https_proxy -fi - -# Change the npm registry mirror if provided -if [ -n "$NPM_MIRROR" ]; then - npm config set registry $NPM_MIRROR -fi - -echo "---> Building application from source..." -npm install - -# Fix permissions -chmod -Rf g+w /opt/app-root/ || true diff --git a/.s2i/bin/run b/.s2i/bin/run deleted file mode 100755 index 870bb05..0000000 --- a/.s2i/bin/run +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash -e -# -# S2I run script for the 'nodejs' image. -# The run script executes the server that runs your application. -# -# For more information see the documentation: -# https://github.com/openshift/source-to-image/blob/master/docs/builder_image.md -# - - -# Runs the nodejs application server. If the container is run in development mode, -# hot deploy and debugging are enabled. -run_node() { - echo -e "Environment: \n\tDEV_MODE=${DEV_MODE}\n\tNODE_ENV=${NODE_ENV}\n\tDEBUG_PORT=${DEBUG_PORT}" - if [ "$DEV_MODE" == true ]; then - echo "Launching via nodemon..." - exec nodemon --debug="$DEBUG_PORT" - else - echo "Launching via npm..." - exec npm run -d $NPM_RUN - fi -} - -#Set the debug port to 5858 by default. -if [ -z "$DEBUG_PORT" ]; then - export DEBUG_PORT=5858 -fi - -# Set the environment to development by default. -if [ -z "$DEV_MODE" ]; then - export DEV_MODE=false -fi - -# If NODE_ENV is not set by the user, then NODE_ENV is determined by whether -# the container is run in development mode. -if [ -z "$NODE_ENV" ]; then - if [ "$DEV_MODE" == true ]; then - export NODE_ENV=development - else - export NODE_ENV=production - fi -fi - -# Allow users to inspect/debug the builder image itself, by using: -# $ docker run -i -t openshift/centos-nodejs-builder --debug -# -[ "$1" == "--debug" ] && exec /bin/bash - -run_node diff --git a/.s2i/bin/usage b/.s2i/bin/usage deleted file mode 100755 index b1a46b4..0000000 --- a/.s2i/bin/usage +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -e -cat < nodejs:6 - -You can then run the resulting image via: -docker run -EOF diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index bf75413..0000000 --- a/Dockerfile +++ /dev/null @@ -1,78 +0,0 @@ -FROM registry.fedoraproject.org/f30/s2i-base:latest - -# This image provides a Node.JS environment you can use to run your Node.JS -# applications. - -EXPOSE 8080 - -# Add $HOME/node_modules/.bin to the $PATH, allowing user to make npm scripts -# available on the CLI without using npm's --global installation mode -# This image will be initialized with "npm run $NPM_RUN" -# See https://docs.npmjs.com/misc/scripts, and your repo's package.json -# file for possible values of NPM_RUN -# Description -# Environment: -# * $NPM_RUN - Select an alternate / custom runtime mode, defined in your package.json files' scripts section (default: npm run "start"). -# Expose ports: -# * 8080 - Unprivileged port used by nodejs application - -ENV NODEJS_VERSION=10 \ - NPM_RUN=start \ - NAME=nodejs \ - NPM_CONFIG_PREFIX=$HOME/.npm-global \ - PATH=$HOME/node_modules/.bin/:$HOME/.npm-global/bin/:$PATH - -ENV SUMMARY="Platform for building and running Node.js $NODEJS_VERSION applications" \ - DESCRIPTION="Node.js $NODEJS_VERSION available as container is a base platform for \ -building and running various Node.js $NODEJS_VERSION applications and frameworks. \ -Node.js is a platform built on Chrome's JavaScript runtime for easily building \ -fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model \ -that makes it lightweight and efficient, perfect for data-intensive real-time applications \ -that run across distributed devices." - -LABEL summary="$SUMMARY" \ - description="$DESCRIPTION" \ - io.k8s.description="$DESCRIPTION" \ - io.k8s.display-name="Node.js $NODEJS_VERSION" \ - io.openshift.expose-services="8080:http" \ - io.openshift.tags="builder,$NAME,$NAME$NODEJS_VERSION" \ - io.openshift.s2i.scripts-url="image:///usr/libexec/s2i" \ - io.s2i.scripts-url="image:///usr/libexec/s2i" \ - com.redhat.dev-mode="DEV_MODE:false" \ - com.redhat.deployments-dir="${APP_ROOT}/src" \ - com.redhat.dev-mode.port="DEBUG_PORT:5858"\ - com.redhat.component="$NAME" \ - name="$FGC/$NAME" \ - version="$NODEJS_VERSION" \ - maintainer="SoftwareCollections.org " \ - help="For more information visit https://github.com/sclorg/s2i-nodejs-container" \ - usage="s2i build centos/$NAME-$NODEJS_VERSION-centos7:latest " - -RUN yum -y module enable nodejs:$NODEJS_VERSION && \ - INSTALL_PKGS="nodejs npm nss_wrapper" && \ - yum remove $INSTALL_PKGS -y && \ - yum install -y --setopt=tsflags=nodocs $INSTALL_PKGS && \ - rpm -V $INSTALL_PKGS && \ - yum -y clean all --enablerepo='*' - -# TODO: Add nodejs-nodemon into Fedora -# https://bugzilla.redhat.com/show_bug.cgi?id=1433784 -#RUN NPM_CONFIG_PREFIX=$HOME/../ npm install -g nodemon && \ -# rm $(npm config get cache)/* -rf && \ -# rm -rf $(npm config get tmp)/npm-* - - -# Copy the S2I scripts from the specific language image to $STI_SCRIPTS_PATH -COPY ./s2i/bin/ $STI_SCRIPTS_PATH - -# Copy extra files to the image, including help file. -COPY ./root/ / - -# Drop the root user and make the content of /opt/app-root owned by user 1001 -RUN chown -R 1001:0 ${APP_ROOT} && chmod -R ug+rwx ${APP_ROOT} && \ - 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/README.md b/README.md deleted file mode 100644 index 6a68a7d..0000000 --- a/README.md +++ /dev/null @@ -1,163 +0,0 @@ -NodeJS 10 container image -=================== - -This container image includes Node.JS 10 as a [S2I](https://github.com/openshift/source-to-image) base image for your Node.JS 10 applications. -Users can choose between RHEL, CentOS and Fedora based images. -The RHEL images are available in the [Red Hat Container Catalog](https://access.redhat.com/containers/), -the CentOS images are available on [Podman Hub](https://hub.docker.com/r/centos/), -and the Fedora images are available in [Fedora Registry](https://registry.fedoraproject.org/). -The resulting image can be run using [podman](https://github.com/containers/libpod). - -Note: while the examples in this README are calling `podman`, you can replace any such calls by `docker` with the same arguments - -Description ------------ - -Node.js 10 available as container is a base platform for -building and running various Node.js 10 applications and frameworks. -Node.js is a platform built on Chrome's JavaScript runtime for easily building -fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model -that makes it lightweight and efficient, perfect for data-intensive real-time applications -that run across distributed devices. - -Usage ---------------------- -For this, we will assume that you are using the `ubi8/nodejs-10 image`, available via `nodejs:10` imagestream tag in Openshift. -Building a simple [nodejs-sample-app](https://github.com/sclorg/s2i-nodejs-container/tree/master/10/test/test-app) application -in Openshift can be achieved with the following step: - - ``` - oc new-app nodejs:10~https://github.com/sclorg/s2i-nodejs-container.git --context-dir=10/test/test-app/ - ``` - -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-nodejs-container.git --context-dir=10/test/test-app/ ubi8/nodejs-10 nodejs-sample-app - ``` - -**Accessing the application:** -``` -$ curl 127.0.0.1:8080 -``` - -Environment variables ---------------------- - -Application developers can use the following environment variables to configure the runtime behavior of this image: - -**`NODE_ENV`** - NodeJS runtime mode (default: "production") - -**`DEV_MODE`** - When set to "true", `nodemon` will be used to automatically reload the server while you work (default: "false"). Setting `DEV_MODE` to "true" will change the `NODE_ENV` default to "development" (if not explicitly set). - -**`NPM_RUN`** - Select an alternate / custom runtime mode, defined in your `package.json` file's [`scripts`](https://docs.npmjs.com/misc/scripts) section (default: npm run "start"). These user-defined run-scripts are unavailable while `DEV_MODE` is in use. - -**`HTTP_PROXY`** - Use an npm proxy during assembly - -**`HTTPS_PROXY`** - Use an npm proxy during assembly - -**`NPM_MIRROR`** - Use a custom NPM registry mirror to download packages during the build process - -One way to define a set of environment variables is to include them as key value pairs in your repo's `.s2i/environment` file. - -Example: DATABASE_USER=sampleUser - -#### NOTE: Define your own "`DEV_MODE`": - -The following `package.json` example includes a `scripts.dev` entry. You can define your own custom [`NPM_RUN`](https://docs.npmjs.com/cli/run-script) scripts in your application's `package.json` file. - -#### Note: Setting logging output verbosity -To alter the level of logs output during an `npm install` the npm_config_loglevel environment variable can be set. See [npm-config](https://docs.npmjs.com/misc/config). - -Development Mode ---------------------- -This image supports development mode. This mode can be switched on and off with the environment variable `DEV_MODE`. `DEV_MODE` can either be set to `true` or `false`. -Development mode supports two features: -* Hot Deploy -* Debugging - -The debug port can be specified with the environment variable `DEBUG_PORT`. `DEBUG_PORT` is only valid if `DEV_MODE=true`. - -A simple example command for running the container in development mode is: -``` -podman run --env DEV_MODE=true my-image-id -``` - -To run the container in development mode with a debug port of 5454, run: -``` -$ podman run --env DEV_MODE=true DEBUG_PORT=5454 my-image-id -``` - -To run the container in production mode, run: -``` -$ podman run --env DEV_MODE=false my-image-id -``` - -By default, `DEV_MODE` is set to `false`, and `DEBUG_PORT` is set to `5858`, however the `DEBUG_PORT` is only relevant if `DEV_MODE=true`. - -Hot deploy --------------------- - -As part of development mode, this image supports hot deploy. If development mode is enabled, any souce code that is changed in the running container will be immediately reflected in the running nodejs application. - -### Using Podman's exec - -To change your source code in a running container, use Podman's [exec](https://github.com/containers/libpod) command: -``` -$ podman exec -it /bin/bash -``` - -After you [Podman exec](https://github.com/containers/libpod) into the running container, your current directory is set to `/opt/app-root/src`, where the source code for your application is located. - -### Using OpenShift's rsync - -If you have deployed the container to OpenShift, you can use [oc rsync](https://docs.openshift.org/latest/dev_guide/copy_files_to_container.html) to copy local files to a remote container running in an OpenShift pod. - -#### Warning: - -The default behaviour of the s2i-nodejs container image is to run the Node.js application using the command `npm start`. This runs the _start_ script in the _package.json_ file. In developer mode, the application is run using the command `nodemon`. The default behaviour of nodemon is to look for the _main_ attribute in the _package.json_ file, and execute that script. If the _main_ attribute doesn't appear in the _package.json_ file, it executes the _start_ script. So, in order to achieve some sort of uniform functionality between production and development modes, the user should remove the _main_ attribute. - -Below is an example _package.json_ file with the _main_ attribute and _start_ script marked appropriately: - -```json -{ - "name": "node-echo", - "version": "0.0.1", - "description": "node-echo", - "main": "example.js", <--- main attribute - "dependencies": { - }, - "devDependencies": { - "nodemon": "*" - }, - "engine": { - "node": "*", - "npm": "*" - }, - "scripts": { - "dev": "nodemon --ignore node_modules/ server.js", - "start": "node server.js" <-- start script - }, - "keywords": [ - "Echo" - ], - "license": "", -} -``` - -#### Note: -`oc rsync` is only available in versions 3.1+ of OpenShift. - - -See also --------- -Dockerfile and other sources are available on https://github.com/sclorg/s2i-nodejs-container. -In that repository you also can find another versions of Python environment Dockerfiles. -Dockerfile for CentOS is called `Dockerfile`, Dockerfile for RHEL7 is called `Dockerfile.rhel7`, -for RHEL8 it's `Dockerfile.rhel8` and the Fedora Dockerfile is called Dockerfile.fedora. diff --git a/common/.travis.yml b/common/.travis.yml deleted file mode 100644 index 8df16d3..0000000 --- a/common/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -language: shell -os: linux -script: - - make shellcheck diff --git a/common/LICENSE b/common/LICENSE deleted file mode 100644 index 7a4a3ea..0000000 --- a/common/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/common/Makefile b/common/Makefile deleted file mode 100644 index ba2b448..0000000 --- a/common/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -SHELL := /usr/bin/env bash - -all: - @echo >&2 "Only 'make check' allowed" - - -TESTED_IMAGES = \ - postgresql-container \ - s2i-python-container \ - s2i-nodejs-container - -.PHONY: check test all check-failures - - -TEST_LIB_TESTS = \ - path_foreach \ - random_string \ - test_npm \ - image_availability \ - public_image_name - -$(TEST_LIB_TESTS): - @echo " RUN TEST '$@'" ; \ - $(SHELL) tests/test-lib/$@ || $(SHELL) -x tests/lib/$@ - -test-lib-foreach: - -check-test-lib: $(TEST_LIB_TESTS) - -test: check - -shellcheck: - ./run-shellcheck.sh `git ls-files *.sh` - -check-failures: check-test-lib - cd tests/failures/check && make tag && ! make check && make clean - grep -q "Red Hat Enterprise Linux release 8" /etc/system-release || cd tests/failures/check && make tag SKIP_SQUASH=0 - -check-squash: - ./tests/squash/squash.sh - -check: check-failures check-squash - TESTED_IMAGES="$(TESTED_IMAGES)" tests/remote-containers.sh diff --git a/common/README.md b/common/README.md deleted file mode 100644 index 4dc9505..0000000 --- a/common/README.md +++ /dev/null @@ -1,100 +0,0 @@ -Common build helpers for sclorg containers -========================================== - -This repository is aimed to be added as git submodule into particular -containers' source repositories. By default, the path to submodule should be -named 'common'. - -Usage ------ - -This section explains the usage of the shared scripts in this repository when -it is used as a submodule in a container source repository. - -Once you have the repository set as a submodule include `common.mk` into your -root Makefile in order to access the default rules used to call shared scripts. - -**Default rules:** - -`make` or `make build` -This rule will build an image without tagging it with any tags after it is built. -After the image finishes building the scripts will squash the image using `docker-squash`. -`make build` will also expect a `README.md` so that it can transfrom it into -a man page that gets added to the image so make sure it is available and that -you have the `go-md2man` tool installed on your host. - - -`make tag` -Use this rule if you want to tag an image after it is built. It will be tagged with -two tags - name:latest and name:version. -Depends on `build` - -`make test` or `make check` -This rule will run the testsuite scripts contained in the container source repositories. -It expects the test to be available at `$gitroot/$version/test/run` -Depends on `tag` as some tests might need to have the images tagged (s2i). - -`make test-openshift` -Similar to `make test` but runs testsuite for Openshift, expected to be found at -`$gitroot/$version/test/run-openshift` - -`make test-with-conu` -The rule is similar to `make test`. It runs a test suite written using [conu -library](https://github.com/user-cont/conu). The path to the test script is -meant to be at `$gitroot/$version/test/run-conu`. By default the test suite is -being run in the current environment. You can also run the tests in a container -by defining variable `CONU_IMAGE`. Container images with conu are available in -[this docker hub repository](docker.io/usercont/conu:0.6.2), a good value for -the variable is `docker.io/usercont/conu:0.6.2`. - -`make clean` -Runs scripts that clean-up the working dir. Depends on the `clean-images` rule by default -and additional clean rules can be provided through the `clean-hook` variable. - -`make clean-images` -Best-effort to remove the last set of images that have been built using the scripts. - -**There are additional variables that you can use that the default rules are prepared to -work with:** - -`VERSIONS` -Names of the directories in which the Dockerfiles are contained. Needs to be defined in your -Dockerfile for the scripts to know which versions to build. - -`OS` -OS version you want to build the images for. Currently the scripts are able to build for -centos (default), centos6, rhel7 and fedora. - -`SKIP_SQUASH` -When set to 1 the build script will skip the squash phase of the build. - -`CUSTOM_REPO` -Set this variable to the path to your local .repo files you want to have available inside -the image while building. Useful for building rhel-based images on an unsubscribed box. -Be aware that you cannot write to any .repo files used this way inside the image as they -will be mounted into the image as read-only. - -`UPDATE_BASE` -Set to 1 if you want the build script to always pull the base image when available. - -`DOCKER_BUILD_CONTEXT` -Use this variable in case you want to have a different context for your builds. By default -the context of the build is the versioned directory the Dockerfiles are contained in. - -`clean-hook` -Append Makefile rules to this variable to make sure additional cleaning actions are run -when `make clean` is called. - -Regression tests ----------------- - -Just run `make check` - -Dependencies for testsuite: - -- docker -- docker-squash -- git -- go-md2man -- make -- source-to-image diff --git a/common/build.sh b/common/build.sh deleted file mode 100755 index 4e78075..0000000 --- a/common/build.sh +++ /dev/null @@ -1,183 +0,0 @@ -#!/bin/bash - -# This script is used to build the OpenShift Docker images. -# -# OS - Specifies distribution - "rhel7", "centos7" or "fedora" -# VERSION - Specifies the image version - (must match with subdirectory in repo) -# VERSIONS - Must be set to a list with possible versions (subdirectories) - -set -e - -script_name=$(readlink -f "$0") -script_dir=$(dirname "$script_name") - -OS=${1-$OS} -VERSION=${2-$VERSION} - -error() { echo "ERROR: $*" ; false ; } - - -# _parse_output_inner -# ------------------- -# Helper function for 'parse_output'. -# We need to avoid case statements in $() for older Bash versions (per issue -# postgresql-container#35, mac ships with 3.2). -# Example of problematic statement: echo $(case i in i) echo i;; esac) -_parse_output_inner () -{ - set -o pipefail - { - case $stream in - stdout|1|"") - eval "$command" | tee >(cat - >&"$stdout_fd") - ;; - stderr|2) - set +x # avoid stderr pollution - eval "$command" {free_fd}>&1 1>&"$stdout_fd" 2>&"$free_fd" | tee >(cat - >&"$stderr_fd") - ;; - esac - # Inherit correct exit status. - (exit "${PIPESTATUS[0]}") - } | eval "$filter" -} - - -# parse_output COMMAND FILTER_COMMAND OUTVAR [STREAM={stderr|stdout}] -# ------------------------------------------------------------------- -# Parse standard (error) output of COMMAND with FILTER_COMMAND and store the -# output into variable named OUTVAR. STREAM might be 'stdout' or 'stderr', -# defaults to 'stdout'. The filtered output stays (live) printed to terminal. -# This method doesn't create any explicit temporary files. -# Defines: -# ${$OUTVAR}: Set to FILTER_COMMAND output. -parse_output () -{ - local command=$1 filter=$2 var=$3 stream=$4 - local raw_output='' rc=0 - { - # shellcheck disable=SC2034 - raw_output=$(_parse_output_inner) - } {stdout_fd}>&1 {stderr_fd}>&2 - rc=$? - eval "$var=\$raw_output" - (exit $rc) -} - -# "best-effort" cleanup of previous image -function clean_image { - if test -f .image-id.raw; then - local previous_id - previous_id=$(cat .image-id.raw) - if test "$IMAGE_ID" != "$previous_id"; then - # Also remove squashed image since it will change anyway - docker rmi "$previous_id" "$(cat .image-id)" || : - rm -f ".image-id.raw" ".image-id" || : - fi - fi -} - -# Perform docker build but append the LABEL with GIT commit id at the end -function docker_build_with_version { - local dockerfile="$1" - local exclude=.exclude-${OS} - if [ -e "$exclude" ]; then - echo "-> $exclude file exists for version $dir, skipping build." - clean_image - return - fi - if [ ! -e "$dockerfile" ]; then - echo "-> $dockerfile for version $dir does not exist, skipping build." - clean_image - return - fi - echo "-> Version ${dir}: building image from '${dockerfile}' ..." - - git_version=$(git rev-parse --short HEAD) - BUILD_OPTIONS+=" --label io.openshift.builder-version=\"${git_version}\"" - if [[ "${UPDATE_BASE}" == "1" ]]; then - BUILD_OPTIONS+=" --pull=true" - fi - if [ -n "$CUSTOM_REPO" ]; then - if [ -f "$CUSTOM_REPO" ]; then - BUILD_OPTIONS+=" -v $CUSTOM_REPO:/etc/yum.repos.d/sclorg_custom.repo:Z" - elif [ -d "$CUSTOM_REPO" ]; then - BUILD_OPTIONS+=" -v $CUSTOM_REPO:/etc/yum.repos.d/:Z" - else - echo "ERROR: file type not known: $CUSTOM_REPO" >&2 - fi - fi - - # shellcheck disable=SC2016 - parse_output 'docker build '"$BUILD_OPTIONS"' -f "$dockerfile" "${DOCKER_BUILD_CONTEXT}"' \ - "tail -n 1 | awk '/Successfully built|(^--> )?(Using cache )?[a-fA-F0-9]+$/{print \$NF}'" \ - IMAGE_ID - clean_image - echo "$IMAGE_ID" > .image-id.raw - - squash "${dockerfile}" - echo "$IMAGE_ID" > .image-id -} - -# squash DOCKERFILE -# ----------------- -# Use python library docker_squash[1] and squash the result image -# when necessary. -# [1] https://github.com/goldmann/docker-squash -# Reads: -# $IMAGE_ID -# Sets: -# $IMAGE_ID -squash () -{ - local base squashed_from squashed='' unsquashed=$IMAGE_ID - test "$SKIP_SQUASH" = 1 && return 0 - - if test -f .image-id.squashed; then - squashed=$(cat .image-id.squashed) - # We (maybe) already have squashed file. - if test -f .image-id.squashed_from; then - squashed_from=$(cat .image-id.squashed_from) - if test "$squashed_from" = "$IMAGE_ID"; then - # $squashed is up2date - IMAGE_ID=$squashed - echo "Image '$unsquashed' already squashed as '$squashed'" - return 0 - fi - fi - - # We are going to squash now, so if there's existing squashed image, try - # to do the best-effort 'rmi' to not waste memory unnecessarily. - docker rmi "$squashed" || : - fi - - base=$(awk '/^FROM/{print $2}' "$1") - - echo "Squashing the image '$unsquashed' from '$base' layer." - IMAGE_ID=$("${PYTHON-python3}" "$script_dir"/squash.py "$unsquashed" "$base") - - echo "Squashed as '$IMAGE_ID'." - - echo "$unsquashed" > .image-id.squashed_from - echo "$IMAGE_ID" > .image-id.squashed -} - -# Versions are stored in subdirectories. You can specify VERSION variable -# to build just one single version. By default we build all versions -dirs=${VERSION:-$VERSIONS} - -for dir in ${dirs}; do - pushd "${dir}" > /dev/null - if [ "$OS" == "rhel8" ] || [ "$OS" == "rhel8-candidate" ]; then - docker_build_with_version Dockerfile.rhel8 - elif [ "$OS" == "rhel7" ] || [ "$OS" == "rhel7-candidate" ]; then - docker_build_with_version Dockerfile.rhel7 - elif [ "$OS" == "fedora" ] || [ "$OS" == "fedora-candidate" ]; then - docker_build_with_version Dockerfile.fedora - elif [ "$OS" == "centos6" ] || [ "$OS" == "centos6-candidate" ]; then - docker_build_with_version Dockerfile.centos6 - else - docker_build_with_version Dockerfile - fi - - popd > /dev/null -done diff --git a/common/clean.sh b/common/clean.sh deleted file mode 100755 index 075d1bf..0000000 --- a/common/clean.sh +++ /dev/null @@ -1,21 +0,0 @@ -#! /bin/sh - -set -e -test -f auto_targets.mk && rm auto_targets.mk - -for version -do - remove_images= - for idfile in .image-id.raw .image-id.squashed; do - # shellcheck disable=SC2039 - test ! -f "$version/$idfile" || remove_images+=" $(cat "$version/$idfile")" - done - - for image in $remove_images; do - # shellcheck disable=SC2046 - docker rm -f $(docker ps -q -a -f "ancestor=$image") 2>/dev/null || : - docker rmi -f "$image" || : - done - - rm -rf "$version"/.image-id* -done diff --git a/common/common.mk b/common/common.mk deleted file mode 100644 index 86682f6..0000000 --- a/common/common.mk +++ /dev/null @@ -1,146 +0,0 @@ -# SKIP_SQUASH = 0/1 -# ================= -# If set to '0', images are automatically squashed. '1' disables -# squashing. By default only RHEL containers are squashed. - -SHELL := /usr/bin/env bash - -ifndef common_dir - common_dir = common -endif - -build = $(SHELL) $(common_dir)/build.sh -test = $(SHELL) $(common_dir)/test.sh -testr = $(SHELL) $(common_dir)/test-remote-cluster.sh -shellcheck = $(SHELL) $(common_dir)/run-shellcheck.sh -tag = $(SHELL) $(common_dir)/tag.sh -clean = $(SHELL) $(common_dir)/clean.sh - -DG ?= /bin/dg - -generator = DG="$(DG)" $(SHELL) $(common_dir)/generate.sh - - -# pretty printers -# --------------- -__PROLOG = $(if $(VERBOSE),,@echo " $(1) " $@;) -V_LN = $(call __PROLOG,LN ) -V_DG = $(call __PROLOG,DG ) -V_DGM = $(call __PROLOG,DGM) -V_CP = $(call __PROLOG,CP ) - -CDIR = mkdir -p "$$(dirname "$@")" || exit 1 ; - -ifeq ($(TARGET),rhel8) - SKIP_SQUASH ?= 1 - OS := rhel8 - DOCKERFILE ?= Dockerfile.rhel8 -else ifeq ($(TARGET),rhel7) - SKIP_SQUASH ?= 0 - OS := rhel7 - DOCKERFILE ?= Dockerfile.rhel7 -else ifeq ($(TARGET),fedora) - OS := fedora - DOCKERFILE ?= Dockerfile.fedora -else ifeq ($(TARGET),centos6) - OS := centos6 - DOCKERFILE ?= Dockerfile.centos6 -else - OS := centos7 - DOCKERFILE ?= Dockerfile -endif - -SKIP_SQUASH ?= 1 -DOCKER_BUILD_CONTEXT ?= . -SHELLCHECK_FILES ?= . - -script_env = \ - SKIP_SQUASH=$(SKIP_SQUASH) \ - UPDATE_BASE=$(UPDATE_BASE) \ - OS=$(OS) \ - CLEAN_AFTER=$(CLEAN_AFTER) \ - DOCKER_BUILD_CONTEXT=$(DOCKER_BUILD_CONTEXT) \ - OPENSHIFT_NAMESPACES="$(OPENSHIFT_NAMESPACES)" \ - CUSTOM_REPO="$(CUSTOM_REPO)" - -# TODO: switch to 'build: build-all' once parallel builds are relatively safe -.PHONY: build build-serial build-all -build: build-serial -build-serial: - @$(MAKE) -j1 build-all - -build-all: $(VERSIONS) - @for i in $(VERSIONS); do \ - test -f $$i/.image-id || continue ; \ - echo -n "$(BASE_IMAGE_NAME) $$i => " ; \ - cat $$i/.image-id ; \ - done - -.PHONY: $(VERSIONS) -$(VERSIONS): % : %/root/help.1 - VERSION="$@" $(script_env) $(build) - -.PHONY: test check -check: test - -test: script_env += TEST_MODE=true - -# The tests should ideally depend on $IMAGE_ID only, but see PR#19 for more info -# while we need to depend on 'tag' instead of 'build'. -test: tag - VERSIONS="$(VERSIONS)" $(script_env) $(test) - -.PHONY: test-with-conu -test-with-conu: script_env += TEST_CONU_MODE=true -test-with-conu: tag - VERSIONS="$(VERSIONS)" $(script_env) $(test) - -.PHONY: test-openshift-remote-cluster -test-openshift-remote-cluster: - VERSIONS="$(VERSIONS)" BASE_IMAGE_NAME="$(BASE_IMAGE_NAME)" $(script_env) $(testr) - -.PHONY: test-openshift -test-openshift: script_env += TEST_OPENSHIFT_MODE=true -test-openshift: tag - VERSIONS="$(VERSIONS)" BASE_IMAGE_NAME="$(BASE_IMAGE_NAME)" $(script_env) $(test) - -.PHONY: shellcheck -shellcheck: - $(shellcheck) $(SHELLCHECK_FILES) - -.PHONY: tag -tag: build - VERSIONS="$(VERSIONS)" $(script_env) $(tag) - -.PHONY: clean clean-hook clean-images clean-versions -clean: clean-images - @$(MAKE) --no-print-directory clean-hook - -clean-images: - $(clean) $(VERSIONS) - -clean-versions: - rm -rf $(VERSIONS) - -%root/help.1: %README.md - mkdir -p $(@D) - go-md2man -in "$^" -out "$@" - chmod a+r "$@" - -generate-all: generate - -MANIFEST_FILE ?= manifest.sh - -auto_targets.mk: $(MANIFEST_FILE) - MANIFEST_FILE="$(MANIFEST_FILE)" \ - VERSIONS="$(VERSIONS)" \ - $(generator) - -# triggers build of auto_targets.mk automatically --include auto_targets.mk - -# We have to remove auto_targets.mk here, otherwise subsequent make calls -# with different VERSIONS=* option keeps the auto_targets.mk unchanged. -.PHONY: generate -generate: $(DISTGEN_TARGETS) $(DISTGEN_MULTI_TARGETS) $(COPY_TARGETS) $(SYMLINK_TARGETS) - rm auto_targets.mk diff --git a/common/generate.sh b/common/generate.sh deleted file mode 100755 index 4c6278b..0000000 --- a/common/generate.sh +++ /dev/null @@ -1,180 +0,0 @@ -#!/bin/bash - -# This script is used to create image directories using distgen, cp or ln -# It requires "$MANIFEST_FILE" (defaults to manifest.sh) file to be present in -# image repository. -# The manifest file should contain set of rules in form: -# =" -# src= -# dest= -# mode=; -# ...; -# " -# -# Supported type rules are now COPY_RULES, DISTGEN_RULES and SYMLINKS_RULES -# for real example see https://github.com/sclorg/postgresql-container/blob/master/manifest.sh - -# shellcheck disable=SC1090 -source "$MANIFEST_FILE" - -die () { echo "FATAL: $*" ; exit 1 ; } - -nl=' -' - -test -f auto_targets.mk && rm auto_targets.mk -DG="${DG-/bin/dg}" -[ ! -x "$DG" ] && echo " Error: distgen binary not found or not executable in $DG" && \ -echo " Make sure distgen is properly installed on your host in $DG, or provide a path to your distgen binary via \$DG" && exit 1 - -DISTGEN_COMBINATIONS=$("$DG" --multispec specs/multispec.yml --multispec-combinations) - - -clean_rule_variables(){ - src="" - dest="" - mode="" - link_target="" - link_name="" -} - -parse_rules() { - targets="" - OLD_IFS=$IFS - IFS=";" - for rule in $rules; do - if [ -z "$(echo "$rule"| tr -d '[:space:]')" ]; then - continue - fi - clean_rule_variables - eval "$rule" - - # shellcheck disable=SC2016 - cdir='$(CDIR)' - case "$creator" in - copy) - [[ -z "$src" ]] && echo "src has to be specified in copy rule" && exit 1 - [[ -z "$dest" ]] && echo "dest has to be specified in copy rule" && exit 1 - core_subst=$core - prolog="\$(V_CP)$cdir" - ;; - distgen) - [[ -z "$src" ]] && echo "src has to be specified in distgen rule" && exit 1 - [[ -z "$dest" ]] && echo "dest has to be specified in distgen rule" && exit 1 - core_subst=$core - prolog="\$(V_DG)$cdir" - ;; - distgen_multi) - [[ -z "$src" ]] && echo "src has to be specified in distgen rule" && exit 1 - [[ -z "$dest" ]] && echo "dest has to be specified in distgen rule" && exit 1 - - if [[ "$dest" == "Dockerfile.rhel7" ]]; then - if ! [[ "$DG_CONF" =~ rhel-7-x86_64.yaml ]]; then - continue - fi - elif [[ "$dest" == "Dockerfile.rhel8" ]]; then - if ! [[ "$DG_CONF" =~ rhel-8-x86_64.yaml ]]; then - continue - fi - elif [[ "$dest" == *"Dockerfile.fedora" ]]; then - if ! [[ "$DG_CONF" =~ fedora-[0-9]{,2}-x86_64.yaml ]]; then - continue - fi - elif [[ "$dest" == *"Dockerfile" ]]; then - if ! [[ "$DG_CONF" =~ centos-[0-9]{,2}-x86_64.yaml ]]; then - continue - fi - fi - prolog="\$(V_DGM)$cdir" - core_subst=$core - ;; - link) - [[ -z "$link_name" ]] && echo "link_name has to be specified in link rule" && exit 1 - [[ -z "$link_target" ]] && echo "link_target has to be specified in link rule" && exit 1 - dest="$link_name" - # shellcheck disable=SC2001 - core_subst=$(echo "$core" | sed -e "s~__link_target__~${link_target}~g") - prolog="\$(V_LN)$cdir" - ;; - esac - - case $version$dest$src in - *' '*) die "space not allowed in version, dest, src" ;; - esac - - target=$version/$dest - targets+="\\$nl $target" - - cat >> auto_targets.mk << EOF -$nl$target: $src \$(MANIFEST_FILE) - $prolog \\ - $core_subst${mode:+"; \\ - chmod $mode '\$@'"} -EOF - done - IFS=$OLD_IFS -} - -for version in ${VERSIONS}; do - # Get a working combination of distgen options for this version - while read -r combination; do - # line looks like: --distro rhel-7-x86_64.yaml --multispec-selector version=9.4 - echo "$combination" | grep "version=$version" &>/dev/null && break - done <<< "$DISTGEN_COMBINATIONS" - [ -z "$combination" ] && die "Could not find a working distgen options combination for version $version" - - # copy targets - rules="$COPY_RULES" - core="cp \$< \$@" - creator="copy" - parse_rules - COPY_TARGETS+="$targets" - - - # distgen targets - rules="$DISTGEN_RULES" - core="\$(DG) --multispec specs/multispec.yml \\ - --template \"\$<\" $combination --output \"\$@\"" - creator="distgen" - parse_rules - DISTGEN_TARGETS+="$targets" - - - rules=$SYMLINK_RULES - core="ln -nfs __link_target__ \$@" - creator="link" - parse_rules - SYMLINK_TARGETS+="$targets" -done - -while read -r combination; do - # line looks like: --distro rhel-7-x86_64.yaml --multispec-selector version=9.4 - eval 'set -- $combination' - case $4 in - version=*) version=${4##*=} ;; - *) die "version not found" - esac - case $2 in - *x86_64*) DG_CONF=$2 ;; - *) die "invalid --distro option" - esac - # distgen multi targets - rules="$DISTGEN_MULTI_RULES" - core="\$(DG) --multispec specs/multispec.yml \\ - --template \"\$<\" \\ - --output \"\$@\" \\ - $combination" - creator="distgen_multi" - parse_rules - DISTGEN_MULTI_TARGETS+="$targets" -done <<< "$DISTGEN_COMBINATIONS" - -cat -v >> auto_targets.mk < [ ... ]" -} - -verbose() { - if [ "${VERBOSE_OUTPUT}" -eq 1 ] ; then - echo "$@" >&2 - fi -} - -if [ $# -eq 0 ] ; then - echo "ERROR: No arguments given." - usage - exit 1 -fi - -case $1 in - -v|--verbose) VERBOSE_OUTPUT=1; shift ;; -esac - -filter_files() { - while read -r file ; do - if [ -L "$file" ] ; then - verbose "Ignoring symlink $file." - continue - fi - verbose "Will scan $file" - echo "$file" - done -} - -detect_shell_files() { - find -H "$@" -type f -not -path '*/\.git/*' -exec grep -l '^#!/bin/\(bash\|sh\)' {} + - find -H "$@" -name '*.sh' -not -path '*/\.git/*' -} - -# Run shellcheck on all files (we should also ignore symlinks) -detect_shell_files "$@" | filter_files | sort -u | xargs shellcheck - -# vim: set tabstop=2:shiftwidth=2:expandtab: diff --git a/common/squash.py b/common/squash.py deleted file mode 100755 index e92de5f..0000000 --- a/common/squash.py +++ /dev/null @@ -1,23 +0,0 @@ -#! /bin/python - -import sys -import logging -from platform import python_version - -try: - from docker_squash import squash -except ImportError: - logging.fatal("please install 'docker_squash' for Python {0}".format(python_version())) - sys.exit(1) - - -if __name__ == "__main__": - if len(sys.argv) != 3: - logging.fatal("%s: %s", sys.argv[0], msg) - sys.exit(1) - - print(squash.Squash( - log=logging.getLogger(), - image=sys.argv[1], - from_layer=sys.argv[2]).run() - ) diff --git a/common/tag.sh b/common/tag.sh deleted file mode 100755 index 0c67aa0..0000000 --- a/common/tag.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash - -# This script is used to tag the OpenShift Docker images. -# -# Resulting image will be tagged: 'name:version' and 'name:latest'. Name and version -# are values of labels from resulted image -# -# VERSIONS - Must be set to a list with possible versions (subdirectories) - -set -e - -for dir in ${VERSIONS}; do - [ ! -e "${dir}/.image-id" ] && echo "-> Image for version $dir not built, skipping tag." && continue - pushd "${dir}" > /dev/null - IMAGE_ID=$(cat .image-id) - name=$(docker inspect -f "{{.Config.Labels.name}}" "$IMAGE_ID") - version=$(docker inspect -f "{{.Config.Labels.version}}" "$IMAGE_ID") - commit_date=$(git show -s HEAD --format=%cd --date=short | sed 's/-//g') - date_and_hash="${commit_date}-$(git rev-parse --short HEAD)" - - echo "-> Tagging image '$IMAGE_ID' as '$name:$version' and '$name:latest' and '$name:$date_and_hash'" - docker tag "$IMAGE_ID" "$name:$version" - docker tag "$IMAGE_ID" "$name:latest" - docker tag "$IMAGE_ID" "$name:$date_and_hash" - - for suffix in squashed raw; do - id_file=.image-id.$suffix - if test -f "$id_file"; then - docker tag "$(cat "$id_file")" "$name:$suffix" || rm .image-id."$suffix" - fi - done - - popd > /dev/null -done diff --git a/common/test-lib-openshift.sh b/common/test-lib-openshift.sh deleted file mode 100644 index 89fc1cf..0000000 --- a/common/test-lib-openshift.sh +++ /dev/null @@ -1,1040 +0,0 @@ -# shellcheck shell=bash -# some functions are used from test-lib.sh, that is usually in the same dir -# shellcheck source=/dev/null -source "$(dirname "${BASH_SOURCE[0]}")"/test-lib.sh - -# Set of functions for testing docker images in OpenShift using 'oc' command - -# A variable containing the overall test result; must be changed to 0 in the end -# of the testing script: -# OS_TESTSUITE_RESULT=0 -# And the following trap must be set, in the beginning of the test script: -# trap ct_os_cleanup EXIT SIGINT -OS_TESTSUITE_RESULT=1 -OS_CLUSTER_STARTED_BY_TEST=0 - -function ct_os_cleanup() { - if [ $OS_TESTSUITE_RESULT -eq 0 ] ; then - # shellcheck disable=SC2153 - echo "OpenShift tests for ${IMAGE_NAME} succeeded." - else - # shellcheck disable=SC2153 - echo "OpenShift tests for ${IMAGE_NAME} failed." - fi -} - -# ct_os_check_compulsory_vars -# --------------------------- -# Check the compulsory variables: -# * IMAGE_NAME specifies a name of the candidate image used for testing. -# * VERSION specifies the major version of the MariaDB in format of X.Y -# * OS specifies RHEL version (e.g. OS=rhel7) -function ct_os_check_compulsory_vars() { - # shellcheck disable=SC2016 - test -n "${IMAGE_NAME-}" || ( echo 'make sure $IMAGE_NAME is defined' >&2 ; exit 1) - # shellcheck disable=SC2016 - test -n "${VERSION-}" || ( echo 'make sure $VERSION is defined' >&2 ; exit 1) - # shellcheck disable=SC2016 - test -n "${OS-}" || ( echo 'make sure $OS is defined' >&2 ; exit 1) -} - -# ct_os_get_status -# -------------------- -# Returns status of all objects to make debugging easier. -function ct_os_get_status() { - oc get all - oc status -} - -# ct_os_print_logs -# -------------------- -# Returns status of all objects and logs from all pods. -function ct_os_print_logs() { - ct_os_get_status - while read -r pod_name; do - echo "INFO: printing logs for pod ${pod_name}" - oc logs "${pod_name}" - done < <(oc get pods --no-headers=true -o custom-columns=NAME:.metadata.name) -} - -# ct_os_enable_print_logs -# -------------------- -# Enables automatic printing of pod logs on ERR. -function ct_os_enable_print_logs() { - set -E - trap ct_os_print_logs ERR -} - -# ct_get_public_ip -# -------------------- -# Returns best guess for the IP that the node is accessible from other computers. -# This is a bit funny heuristic, simply goes through all IPv4 addresses that -# hostname -I returns and de-prioritizes IP addresses commonly used for local -# addressing. The rest of addresses are taken as public with higher probability. -function ct_get_public_ip() { - local hostnames - local public_ip='' - local found_ip - hostnames=$(hostname -I) - for guess_exp in '127\.0\.0\.1' '192\.168\.[0-9\.]*' '172\.[0-9\.]*' \ - '10\.[0-9\.]*' '[0-9\.]*' ; do - found_ip=$(echo "${hostnames}" | grep -oe "${guess_exp}") - if [ -n "${found_ip}" ] ; then - # shellcheck disable=SC2001 - hostnames=$(echo "${hostnames}" | sed -e "s/${found_ip}//") - public_ip="${found_ip}" - fi - done - if [ -z "${public_ip}" ] ; then - echo "ERROR: public IP could not be guessed." >&2 - return 1 - fi - echo "${public_ip}" -} - -# ct_os_run_in_pod POD_NAME CMD -# -------------------- -# Runs [cmd] in the pod specified by prefix [pod_prefix]. -# Arguments: pod_name - full name of the pod -# Arguments: cmd - command to be run in the pod -function ct_os_run_in_pod() { - local pod_name="$1" ; shift - - oc exec "$pod_name" -- "$@" -} - -# ct_os_get_service_ip SERVICE_NAME -# -------------------- -# Returns IP of the service specified by [service_name]. -# Arguments: service_name - name of the service -function ct_os_get_service_ip() { - local service_name="${1}" ; shift - oc get "svc/${service_name}" -o yaml | grep clusterIP | \ - cut -d':' -f2 | grep -oe '172\.30\.[0-9\.]*' -} - - -# ct_os_get_all_pods_status -# -------------------- -# Returns status of all pods. -function ct_os_get_all_pods_status() { - oc get pods -o custom-columns=Ready:status.containerStatuses[0].ready,NAME:.metadata.name -} - -# ct_os_get_all_pods_name -# -------------------- -# Returns the full name of all pods. -function ct_os_get_all_pods_name() { - oc get pods --no-headers -o custom-columns=NAME:.metadata.name -} - -# ct_os_get_pod_status POD_PREFIX -# -------------------- -# Returns status of the pod specified by prefix [pod_prefix]. -# Note: Ignores -build and -deploy pods -# Arguments: pod_prefix - prefix or whole ID of the pod -function ct_os_get_pod_status() { - local pod_prefix="${1}" ; shift - ct_os_get_all_pods_status | grep -e "${pod_prefix}" | grep -Ev "(build|deploy)$" \ - | awk '{print $1}' | head -n 1 -} - -# ct_os_get_pod_name POD_PREFIX -# -------------------- -# Returns the full name of pods specified by prefix [pod_prefix]. -# Note: Ignores -build and -deploy pods -# Arguments: pod_prefix - prefix or whole ID of the pod -function ct_os_get_pod_name() { - local pod_prefix="${1}" ; shift - ct_os_get_all_pods_name | grep -e "^${pod_prefix}" | grep -Ev "(build|deploy)$" -} - -# ct_os_get_pod_ip POD_NAME -# -------------------- -# Returns the ip of the pod specified by [pod_name]. -# Arguments: pod_name - full name of the pod -function ct_os_get_pod_ip() { - local pod_name="${1}" - oc get pod "$pod_name" --no-headers -o custom-columns=IP:status.podIP -} - -# ct_os_check_pod_readiness POD_PREFIX STATUS -# -------------------- -# Checks whether the pod is ready. -# Arguments: pod_prefix - prefix or whole ID of the pod -# Arguments: status - expected status (true, false) -function ct_os_check_pod_readiness() { - local pod_prefix="${1}" ; shift - local status="${1}" ; shift - test "$(ct_os_get_pod_status "${pod_prefix}")" == "${status}" -} - -# ct_os_wait_pod_ready POD_PREFIX TIMEOUT -# -------------------- -# Wait maximum [timeout] for the pod becomming ready. -# Arguments: pod_prefix - prefix or whole ID of the pod -# Arguments: timeout - how many seconds to wait seconds -function ct_os_wait_pod_ready() { - local pod_prefix="${1}" ; shift - local timeout="${1}" ; shift - SECONDS=0 - echo -n "Waiting for ${pod_prefix} pod becoming ready ..." - while ! ct_os_check_pod_readiness "${pod_prefix}" "true" ; do - echo -n "." - [ "${SECONDS}" -gt "${timeout}" ] && echo " FAIL" && return 1 - sleep 3 - done - echo " DONE" -} - -# ct_os_wait_rc_ready POD_PREFIX TIMEOUT -# -------------------- -# Wait maximum [timeout] for the rc having desired number of replicas ready. -# Arguments: pod_prefix - prefix of the replication controller -# Arguments: timeout - how many seconds to wait seconds -function ct_os_wait_rc_ready() { - local pod_prefix="${1}" ; shift - local timeout="${1}" ; shift - SECONDS=0 - echo -n "Waiting for ${pod_prefix} pod becoming ready ..." - while ! test "$( (oc get --no-headers statefulsets; oc get --no-headers rc) 2>/dev/null \ - | grep "^${pod_prefix}" | awk '$2==$3 {print "ready"}')" == "ready" ; do - echo -n "." - [ "${SECONDS}" -gt "${timeout}" ] && echo " FAIL" && return 1 - sleep 3 - done - echo " DONE" -} - -# ct_os_deploy_pure_image IMAGE [ENV_PARAMS, ...] -# -------------------- -# Runs [image] in the openshift and optionally specifies env_params -# as environment variables to the image. -# Arguments: image - prefix or whole ID of the pod to run the cmd in -# Arguments: env_params - environment variables parameters for the images. -function ct_os_deploy_pure_image() { - local image="${1}" ; shift - # ignore error exit code, because oc new-app returns error when image exists - oc new-app "${image}" "$@" || : - # let openshift cluster to sync to avoid some race condition errors - sleep 3 -} - -# ct_os_deploy_s2i_image IMAGE APP [ENV_PARAMS, ... ] -# -------------------- -# Runs [image] and [app] in the openshift and optionally specifies env_params -# as environment variables to the image. -# Arguments: image - prefix or whole ID of the pod to run the cmd in -# Arguments: app - url or local path to git repo with the application sources. -# Arguments: env_params - environment variables parameters for the images. -function ct_os_deploy_s2i_image() { - local image="${1}" ; shift - local app="${1}" ; shift - # ignore error exit code, because oc new-app returns error when image exists - oc new-app "${image}~${app}" "$@" || : - - # let openshift cluster to sync to avoid some race condition errors - sleep 3 -} - -# ct_os_deploy_template_image TEMPLATE [ENV_PARAMS, ...] -# -------------------- -# Runs template in the openshift and optionally gives env_params to use -# specific values in the template. -# Arguments: template - prefix or whole ID of the pod to run the cmd in -# Arguments: env_params - environment variables parameters for the template. -# Example usage: ct_os_deploy_template_image mariadb-ephemeral-template.yaml \ -# DATABASE_SERVICE_NAME=mysql-57-centos7 \ -# DATABASE_IMAGE=mysql-57-centos7 \ -# MYSQL_USER=testu \ -# MYSQL_PASSWORD=testp \ -# MYSQL_DATABASE=testdb -function ct_os_deploy_template_image() { - local template="${1}" ; shift - oc process -f "${template}" "$@" | oc create -f - - # let openshift cluster to sync to avoid some race condition errors - sleep 3 -} - -# _ct_os_get_uniq_project_name -# -------------------- -# Returns a uniq name of the OpenShift project. -function _ct_os_get_uniq_project_name() { - local r - while true ; do - r=${RANDOM} - mkdir /var/tmp/sclorg-test-${r} &>/dev/null && echo sclorg-test-${r} && break - done -} - -# ct_os_new_project [PROJECT] -# -------------------- -# Creates a new project in the openshfit using 'os' command. -# Arguments: project - project name, uses a new random name if omitted -# Expects 'os' command that is properly logged in to the OpenShift cluster. -# Not using mktemp, because we cannot use uppercase characters. -# The OPENSHIFT_CLUSTER_PULLSECRET_PATH environment variable can be set -# to contain a path to a k8s secret definition which will be used -# to authenticate to image registries. -# shellcheck disable=SC2120 -function ct_os_new_project() { - if [ "${CT_SKIP_NEW_PROJECT:-false}" == 'true' ] ; then - echo "Creating project skipped." - return - fi - local project_name="${1:-$(_ct_os_get_uniq_project_name)}" ; shift || : - oc new-project "${project_name}" - # let openshift cluster to sync to avoid some race condition errors - sleep 3 - if test -n "${OPENSHIFT_CLUSTER_PULLSECRET_PATH:-}" -a -e "${OPENSHIFT_CLUSTER_PULLSECRET_PATH:-}"; then - oc create -f "$OPENSHIFT_CLUSTER_PULLSECRET_PATH" - # add registry pullsecret to the serviceaccount if provided - secret_name=$(grep '^\s*name:' "$OPENSHIFT_CLUSTER_PULLSECRET_PATH" | awk '{ print $2 }') - oc secrets link --for=pull default "$secret_name" - fi -} - -# ct_os_delete_project [PROJECT] -# -------------------- -# Deletes the specified project in the openshfit -# Arguments: project - project name, uses the current project if omitted -# shellcheck disable=SC2120 -function ct_os_delete_project() { - if [ "${CT_SKIP_NEW_PROJECT:-false}" == 'true' ] ; then - echo "Deleting project skipped, cleaning objects only." - # when not having enough privileges (remote cluster), it might fail and - # it is not a big problem, so ignore failure in this case - ct_delete_all_objects || : - return - fi - local project_name="${1:-$(oc project -q)}" ; shift || : - oc delete project "${project_name}" -} - -# ct_delete_all_objects -# ----------------- -# Deletes all objects within the project. -# Handy when we have one project and want to run more tests. -function ct_delete_all_objects() { - for x in bc builds dc is isimage istag po pv pvc rc routes secrets svc ; do - oc delete "$x" --all - done - # for some objects it takes longer to be really deleted, so a dummy sleep - # to avoid some races when other test can see not-yet-deleted objects and can fail - sleep 10 -} - -# ct_os_docker_login -# -------------------- -# Logs in into docker daemon -# Uses global REGISRTY_ADDRESS environment variable for arbitrary registry address. -# Does not do anything if REGISTRY_ADDRESS is set. -function ct_os_docker_login() { - [ -n "${REGISTRY_ADDRESS:-}" ] && "REGISTRY_ADDRESS set, not trying to docker login." && return 0 - # docker login fails with "404 page not found" error sometimes, just try it more times - # shellcheck disable=SC2034 - for i in $(seq 12) ; do - # shellcheck disable=SC2015 - docker login -u developer -p "$(oc whoami -t)" "${REGISRTY_ADDRESS:-172.30.1.1:5000}" && return 0 || : - sleep 5 - done - return 1 -} - -# ct_os_upload_image IMAGE [IMAGESTREAM] -# -------------------- -# Uploads image from local registry to the OpenShift internal registry. -# Arguments: image - image name to upload -# Arguments: imagestream - name and tag to use for the internal registry. -# In the format of name:tag ($image_name:latest by default) -# Uses global REGISRTY_ADDRESS environment variable for arbitrary registry address. -function ct_os_upload_image() { - local input_name="${1}" ; shift - local image_name=${input_name##*/} - local imagestream=${1:-$image_name:latest} - local output_name - - output_name="${REGISRTY_ADDRESS:-172.30.1.1:5000}/$(oc project -q)/$imagestream" - - ct_os_docker_login - docker tag "${input_name}" "${output_name}" - docker push "${output_name}" -} - -# ct_os_is_tag_exists IS_NAME TAG -# -------------------- -# Checks whether the specified tag exists for an image stream -# Arguments: is_name - name of the image stream -# Arguments: tag - name of the tag (usually version) -function ct_os_is_tag_exists() { - local is_name=$1 ; shift - local tag=$1 ; shift - oc get is "${is_name}" -n openshift -o=jsonpath='{.spec.tags[*].name}' | grep -qw "${tag}" -} - -# ct_os_template_exists T_NAME -# -------------------- -# Checks whether the specified template exists for an image stream -# Arguments: t_name - template name of the image stream -function ct_os_template_exists() { - local t_name=$1 ; shift - oc get templates -n openshift | grep -q "^${t_name}\s" -} - -# ct_os_install_in_centos -# -------------------- -# Installs os cluster in CentOS -function ct_os_install_in_centos() { - yum install -y centos-release-openshift-origin - yum install -y wget git net-tools bind-utils iptables-services bridge-utils\ - bash-completion origin-clients docker origin-clients -} - -# ct_os_cluster_up [DIR, IS_PUBLIC, CLUSTER_VERSION] -# -------------------- -# Runs the local OpenShift cluster using 'oc cluster up' and logs in as developer. -# Arguments: dir - directory to keep configuration data in, random if omitted -# Arguments: is_public - sets either private or public hostname for web-UI, -# use "true" for allow remote access to the web-UI, -# "false" is default -# Arguments: cluster_version - version of the OpenShift cluster to use, empty -# means default version of `oc`; example value: 3.7; -# also can be specified outside by OC_CLUSTER_VERSION -function ct_os_cluster_up() { - ct_os_cluster_running && echo "Cluster already running. Nothing is done." && return 0 - ct_os_logged_in && echo "Already logged in to a cluster. Nothing is done." && return 0 - - mkdir -p /var/tmp/openshift - local dir="${1:-$(mktemp -d /var/tmp/openshift/os-data-XXXXXX)}" ; shift || : - local is_public="${1:-'false'}" ; shift || : - local default_cluster_version=${OC_CLUSTER_VERSION:-} - local cluster_version=${1:-${default_cluster_version}} ; shift || : - if ! grep -qe '--insecure-registry.*172\.30\.0\.0' /etc/sysconfig/docker ; then - sed -i "s|OPTIONS='|OPTIONS='--insecure-registry 172.30.0.0/16 |" /etc/sysconfig/docker - fi - - systemctl stop firewalld || : - setenforce 0 - iptables -F - - systemctl restart docker - local cluster_ip="127.0.0.1" - [ "${is_public}" == "true" ] && cluster_ip=$(ct_get_public_ip) - - if [ -n "${cluster_version}" ] ; then - # if $cluster_version is not set, we simply use oc that is available - ct_os_set_path_oc "${cluster_version}" - fi - - mkdir -p "${dir}"/{config,data,pv} - case $(oc version| head -n 1) in - "oc v3.1"?.*) - oc cluster up --base-dir="${dir}/data" --public-hostname="${cluster_ip}" - ;; - "oc v3."*) - oc cluster up --host-data-dir="${dir}/data" --host-config-dir="${dir}/config" \ - --host-pv-dir="${dir}/pv" --use-existing-config --public-hostname="${cluster_ip}" - ;; - *) - echo "ERROR: Unexpected oc version." >&2 - return 1 - ;; - esac - oc version - oc login -u system:admin - oc project default - ct_os_wait_rc_ready docker-registry 180 - ct_os_wait_rc_ready router 30 - oc login -u developer -p developer - OS_CLUSTER_STARTED_BY_TEST=1 - # let openshift cluster to sync to avoid some race condition errors - sleep 3 -} - -# ct_os_cluster_down -# -------------------- -# Shuts down the local OpenShift cluster using 'oc cluster down' -function ct_os_cluster_down() { - if [ ${OS_CLUSTER_STARTED_BY_TEST:-0} -eq 1 ] ; then - echo "Cluster started by the test, shutting down." - oc cluster down - else - echo "Cluster not started by the test, shutting down skipped." - fi -} - -# ct_os_cluster_running -# -------------------- -# Returns 0 if oc cluster is running -function ct_os_cluster_running() { - oc cluster status &>/dev/null -} - -# ct_os_logged_in -# --------------- -# Returns 0 if logged in to a cluster (remote or local) -function ct_os_logged_in() { - oc whoami >/dev/null -} - -# ct_os_set_path_oc OC_VERSION -# -------------------- -# This is a trick that helps using correct version of the `oc`: -# The input is version of the openshift in format v3.6.0 etc. -# If the currently available version of oc is not of this version, -# it first takes a look into /usr/local/oc-/bin directory, -# and if not found there it downloads the community release from github. -# In the end the PATH variable is changed, so the other tests can still use just 'oc'. -# Arguments: oc_version - X.Y part of the version of OSE (e.g. 3.9) -function ct_os_set_path_oc() { - local oc_version - local oc_path - - oc_version=$(ct_os_get_latest_ver "$1") - - if oc version | grep -q "oc ${oc_version%.*}." ; then - echo "Binary oc found already available in version ${oc_version}: $(command -v oc) Doing noting." - return 0 - fi - - # first check whether we already have oc available in /usr/local - local installed_oc_path="/usr/local/oc-${oc_version%.*}/bin" - - if [ -x "${installed_oc_path}/oc" ] ; then - oc_path="${installed_oc_path}" - echo "Binary oc found in ${installed_oc_path}" >&2 - else - # oc not available in /usr/local, try to download it from github (community release) - oc_path="/tmp/oc-${oc_version}-bin" - ct_os_download_upstream_oc "${oc_version}" "${oc_path}" - fi - if [ -z "${oc_path}" ] ; then - echo "ERROR: oc not found installed, nor downloaded" >&1 - return 1 - fi - export PATH="${oc_path}:${PATH}" - if ! oc version | grep -q "oc ${oc_version%.*}." ; then - echo "ERROR: something went wrong, oc located at ${oc_path}, but oc of version ${oc_version} not found in PATH ($PATH)" >&1 - return 1 - else - echo "PATH set correctly, binary oc found in version ${oc_version}: $(command -v oc)" - fi -} - -# ct_os_get_latest_ver VERSION_PART_X -# -------------------- -# Returns full version (vX.Y.Z) from part of the version (X.Y) -# Arguments: vxy - X.Y part of the version -# Returns vX.Y.Z variant of the version -function ct_os_get_latest_ver(){ - local vxy="v$1" - for vz in {3..0} ; do - curl -sif "https://github.com/openshift/origin/releases/tag/${vxy}.${vz}" >/dev/null && echo "${vxy}.${vz}" && return 0 - done - echo "ERROR: version ${vxy} not found in https://github.com/openshift/origin/tags" >&2 - return 1 -} - -# ct_os_download_upstream_oc OC_VERSION OUTPUT_DIR -# -------------------- -# Downloads a particular version of openshift-origin-client-tools from -# github into specified output directory -# Arguments: oc_version - version of OSE (e.g. v3.7.2) -# Arguments: output_dir - output directory -function ct_os_download_upstream_oc() { - local oc_version=$1 - local output_dir=$2 - - # check whether we already have the binary in place - [ -x "${output_dir}/oc" ] && return 0 - - mkdir -p "${output_dir}" - # using html output instead of https://api.github.com/repos/openshift/origin/releases/tags/${oc_version}, - # because API is limited for number of queries if not authenticated - tarball=$(curl -si "https://github.com/openshift/origin/releases/tag/${oc_version}" | grep -o -e "openshift-origin-client-tools-${oc_version}-[a-f0-9]*-linux-64bit.tar.gz" | head -n 1) - - # download, unpack the binaries and then put them into output directory - echo "Downloading https://github.com/openshift/origin/releases/download/${oc_version}/${tarball} into ${output_dir}/" >&2 - curl -sL https://github.com/openshift/origin/releases/download/"${oc_version}"/"${tarball}" | tar -C "${output_dir}" -xz - mv -f "${output_dir}"/"${tarball%.tar.gz}"/* "${output_dir}/" - - rmdir "${output_dir}"/"${tarball%.tar.gz}" -} - - -# ct_os_test_s2i_app_func IMAGE APP CONTEXT_DIR CHECK_CMD [OC_ARGS] -# -------------------- -# Runs [image] and [app] in the openshift and optionally specifies env_params -# as environment variables to the image. Then check the container by arbitrary -# function given as argument (such an argument may include string, -# that will be replaced with actual IP). -# Arguments: image - prefix or whole ID of the pod to run the cmd in (compulsory) -# Arguments: app - url or local path to git repo with the application sources (compulsory) -# Arguments: context_dir - sub-directory inside the repository with the application sources (compulsory) -# Arguments: check_command - CMD line that checks whether the container works (compulsory; '' will be replaced with actual IP) -# Arguments: oc_args - all other arguments are used as additional parameters for the `oc new-app` -# command, typically environment variables (optional) -function ct_os_test_s2i_app_func() { - local image_name=${1} - local app=${2} - local context_dir=${3} - local check_command=${4} - local oc_args=${5:-} - local import_image=${6:-} - local image_name_no_namespace=${image_name##*/} - local service_name="${image_name_no_namespace}-testing" - local image_tagged="${image_name_no_namespace}:${VERSION}" - - if [ $# -lt 4 ] || [ -z "${1}" ] || [ -z "${2}" ] || [ -z "${3}" ] || [ -z "${4}" ]; then - echo "ERROR: ct_os_test_s2i_app_func() requires at least 4 arguments that cannot be emtpy." >&2 - return 1 - fi - - # shellcheck disable=SC2119 - ct_os_new_project - # Create a specific imagestream tag for the image so that oc cannot use anything else - if [ "${CT_SKIP_UPLOAD_IMAGE:-false}" == 'true' ] ; then - if [ -n "${import_image}" ] ; then - echo "Importing image ${import_image} as ${image_name}:${VERSION}" - # 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 import-image "${image_name}":"${VERSION}" --from "${import_image}" --confirm --reference-policy=local - else - echo "Uploading and importing image skipped." - fi - else - ct_os_upload_image "${import_image:-$image_name}" "${image_tagged}" - fi - - local app_param="${app}" - if [ -d "${app}" ] ; then - # for local directory, we need to copy the content, otherwise too smart os command - # pulls the git remote repository instead - app_param=$(ct_obtain_input "${app}") - fi - - # shellcheck disable=SC2086 - ct_os_deploy_s2i_image "${image_tagged}" "${app_param}" \ - --context-dir="${context_dir}" \ - --name "${service_name}" \ - ${oc_args} - - if [ -d "${app}" ] ; then - # in order to avoid weird race seen sometimes, let's wait shortly - # before starting the build explicitly - sleep 5 - oc start-build "${service_name}" --from-dir="${app_param}" - fi - - ct_os_wait_pod_ready "${service_name}" 300 - - local ip - local check_command_exp - - ip=$(ct_os_get_service_ip "${service_name}") - # shellcheck disable=SC2001 - check_command_exp=$(echo "$check_command" | sed -e "s//$ip/g") - - echo " Checking APP using $check_command_exp ..." - local result=0 - eval "$check_command_exp" || result=1 - - if [ $result -eq 0 ] ; then - echo " Check passed." - else - echo " Check failed." - fi - - # shellcheck disable=SC2119 - ct_os_delete_project - return $result -} - -# ct_os_test_s2i_app IMAGE APP CONTEXT_DIR EXPECTED_OUTPUT [PORT, PROTOCOL, RESPONSE_CODE, OC_ARGS, ... ] -# -------------------- -# Runs [image] and [app] in the openshift and optionally specifies env_params -# as environment variables to the image. Then check the http response. -# Arguments: image - prefix or whole ID of the pod to run the cmd in (compulsory) -# Arguments: app - url or local path to git repo with the application sources (compulsory) -# Arguments: context_dir - sub-directory inside the repository with the application sources (compulsory) -# Arguments: expected_output - PCRE regular expression that must match the response body (compulsory) -# Arguments: port - which port to use (optional; default: 8080) -# Arguments: protocol - which protocol to use (optional; default: http) -# Arguments: response_code - what http response code to expect (optional; default: 200) -# Arguments: oc_args - all other arguments are used as additional parameters for the `oc new-app` -# command, typically environment variables (optional) -function ct_os_test_s2i_app() { - local image_name=${1} - local app=${2} - local context_dir=${3} - local expected_output=${4} - local port=${5:-8080} - local protocol=${6:-http} - local response_code=${7:-200} - local oc_args=${8:-} - local import_image=${9:-} - - if [ $# -lt 4 ] || [ -z "${1}" ] || [ -z "${2}" ] || [ -z "${3}" ] || [ -z "${4}" ]; then - echo "ERROR: ct_os_test_s2i_app() requires at least 4 arguments that cannot be emtpy." >&2 - return 1 - fi - - ct_os_test_s2i_app_func "${image_name}" \ - "${app}" \ - "${context_dir}" \ - "ct_os_test_response_internal '${protocol}://:${port}' '${response_code}' '${expected_output}'" \ - "${oc_args}" "${import_image}" -} - -# ct_os_test_template_app_func IMAGE APP IMAGE_IN_TEMPLATE CHECK_CMD [OC_ARGS] -# -------------------- -# Runs [image] and [app] in the openshift and optionally specifies env_params -# as environment variables to the image. Then check the container by arbitrary -# function given as argument (such an argument may include string, -# that will be replaced with actual IP). -# Arguments: image_name - prefix or whole ID of the pod to run the cmd in (compulsory) -# Arguments: template - url or local path to a template to use (compulsory) -# Arguments: name_in_template - image name used in the template -# Arguments: check_command - CMD line that checks whether the container works (compulsory; '' will be replaced with actual IP) -# Arguments: oc_args - all other arguments are used as additional parameters for the `oc new-app` -# command, typically environment variables (optional) -# Arguments: other_images - some templates need other image to be pushed into the OpenShift registry, -# specify them in this parameter as "|", where "" is a full image name -# (including registry if needed) and "" is a tag under which the image should be available -# in the OpenShift registry. -function ct_os_test_template_app_func() { - local image_name=${1} - local template=${2} - local name_in_template=${3} - local check_command=${4} - local oc_args=${5:-} - local other_images=${6:-} - local import_image=${7:-} - - if [ $# -lt 4 ] || [ -z "${1}" ] || [ -z "${2}" ] || [ -z "${3}" ] || [ -z "${4}" ]; then - echo "ERROR: ct_os_test_template_app_func() requires at least 4 arguments that cannot be emtpy." >&2 - return 1 - fi - - local service_name="${name_in_template}-testing" - local image_tagged="${name_in_template}:${VERSION}" - - # shellcheck disable=SC2119 - ct_os_new_project - - # Create a specific imagestream tag for the image so that oc cannot use anything else - if [ "${CT_SKIP_UPLOAD_IMAGE:-false}" == 'true' ] ; then - if [ -n "${import_image}" ] ; then - echo "Importing image ${import_image} as ${image_name}:${VERSION}" - # 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 import-image "${image_name}":"${VERSION}" --from "${import_image}" --confirm --reference-policy=local - else - echo "Uploading and importing image skipped." - fi - else - ct_os_upload_image "${import_image:-$image_name}" "${image_tagged}" - - # upload also other images, that template might need (list of pairs in the format | - local image_tag_a - local i_t - for i_t in ${other_images} ; do - echo "${i_t}" - IFS='|' read -ra image_tag_a <<< "${i_t}" - docker pull "${image_tag_a[0]}" - ct_os_upload_image "${image_tag_a[0]}" "${image_tag_a[1]}" - done - fi - - # get the template file from remote or local location; if not found, it is - # considered an internal template name, like 'mysql', so use the name - # explicitly - local local_template - local namespace - - namespace=${CT_NAMESPACE:-$(oc project -q)} - - local_template=$(ct_obtain_input "${template}" 2>/dev/null || echo "--template=${template}") - # shellcheck disable=SC2086 - oc new-app "${local_template}" \ - --name "${name_in_template}" \ - -p NAMESPACE="${namespace}" \ - ${oc_args} - - ct_os_wait_pod_ready "${service_name}" 300 - - local ip - local check_command_exp - - ip=$(ct_os_get_service_ip "${service_name}") - # shellcheck disable=SC2001 - check_command_exp=$(echo "$check_command" | sed -e "s//$ip/g") - - echo " Checking APP using $check_command_exp ..." - local result=0 - eval "$check_command_exp" || result=1 - - if [ $result -eq 0 ] ; then - echo " Check passed." - else - echo " Check failed." - fi - - # shellcheck disable=SC2119 - ct_os_delete_project - return $result -} - -# params: -# ct_os_test_template_app IMAGE APP IMAGE_IN_TEMPLATE EXPECTED_OUTPUT [PORT, PROTOCOL, RESPONSE_CODE, OC_ARGS, ... ] -# -------------------- -# Runs [image] and [app] in the openshift and optionally specifies env_params -# as environment variables to the image. Then check the http response. -# Arguments: image_name - prefix or whole ID of the pod to run the cmd in (compulsory) -# Arguments: template - url or local path to a template to use (compulsory) -# Arguments: name_in_template - image name used in the template -# Arguments: expected_output - PCRE regular expression that must match the response body (compulsory) -# Arguments: port - which port to use (optional; default: 8080) -# Arguments: protocol - which protocol to use (optional; default: http) -# Arguments: response_code - what http response code to expect (optional; default: 200) -# Arguments: oc_args - all other arguments are used as additional parameters for the `oc new-app` -# command, typically environment variables (optional) -# Arguments: other_images - some templates need other image to be pushed into the OpenShift registry, -# specify them in this parameter as "|", where "" is a full image name -# (including registry if needed) and "" is a tag under which the image should be available -# in the OpenShift registry. -function ct_os_test_template_app() { - local image_name=${1} - local template=${2} - local name_in_template=${3} - local expected_output=${4} - local port=${5:-8080} - local protocol=${6:-http} - local response_code=${7:-200} - local oc_args=${8:-} - local other_images=${9:-} - local import_image=${10:-} - - if [ $# -lt 4 ] || [ -z "${1}" ] || [ -z "${2}" ] || [ -z "${3}" ] || [ -z "${4}" ]; then - echo "ERROR: ct_os_test_template_app() requires at least 4 arguments that cannot be emtpy." >&2 - return 1 - fi - - ct_os_test_template_app_func "${image_name}" \ - "${template}" \ - "${name_in_template}" \ - "ct_os_test_response_internal '${protocol}://:${port}' '${response_code}' '${expected_output}'" \ - "${oc_args}" \ - "${other_images}" \ - "${import_image}" -} - -# ct_os_test_image_update IMAGE_NAME OLD_IMAGE ISTAG CHECK_FUNCTION OC_ARGS -# -------------------- -# Runs an image update test with [image] uploaded to [is] imagestream -# and checks the services using an arbitrary function provided in [check_function]. -# Arguments: image_name - prefix or whole ID of the pod to run the cmd in (compulsory) -# Arguments: old_image - valid name of the image from the registry -# Arguments: istag - imagestream to upload the images into (compulsory) -# Arguments: check_function - command to be run to check functionality of created services (compulsory) -# Arguments: oc_args - arguments to use during oc new-app (compulsory) -ct_os_test_image_update() { - local image_name=$1; shift - local old_image=$1; shift - local istag=$1; shift - local check_function=$1; shift - local service_name=${image_name##*/} - local ip="" check_command_exp="" - - echo "Running image update test for: $image_name" - # shellcheck disable=SC2119 - ct_os_new_project - - # Get current image from repository and create an imagestream - docker pull "$old_image:latest" 2>/dev/null - ct_os_upload_image "$old_image" "$istag" - - # Setup example application with curent image - oc new-app "$@" --name "$service_name" - ct_os_wait_pod_ready "$service_name" 60 - - # Check application output - ip=$(ct_os_get_service_ip "$service_name") - check_command_exp=${check_function///$ip} - ct_assert_cmd_success "$check_command_exp" - - # Tag built image into the imagestream and wait for rebuild - ct_os_upload_image "$image_name" "$istag" - ct_os_wait_pod_ready "${service_name}-2" 60 - - # Check application output - ip=$(ct_os_get_service_ip "$service_name") - check_command_exp=${check_function///$ip} - ct_assert_cmd_success "$check_command_exp" - - # shellcheck disable=SC2119 - ct_os_delete_project -} - -# ct_os_deploy_cmd_image IMAGE_NAME -# -------------------- -# Runs a special command pod, a pod that does nothing, but includes utilities for testing. -# A typical usage is a mysql pod that includes mysql commandline, that we need for testing. -# Running commands inside this command pod is done via ct_os_cmd_image_run function. -# The pod is not run again if already running. -# Arguments: image_name - image to be used as a command pod -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" - oc create -f - <" - local sleep_time=3 - local attempt=1 - local result=1 - local status - local response_code - local response_file - local util_image_name='python:3.6' - - response_file=$(mktemp /tmp/ct_test_response_XXXXXX) - ct_os_deploy_cmd_image "${util_image_name}" - - while [ "${attempt}" -le "${max_attempts}" ]; do - ct_os_cmd_image_run "curl --connect-timeout 10 -s -w '%{http_code}' '${url}'" >"${response_file}" && status=0 || status=1 - if [ "${status}" -eq 0 ]; then - response_code=$(tail -c 3 "${response_file}") - if [ "${response_code}" -eq "${expected_code}" ]; then - result=0 - fi - grep -qP -e "${body_regexp}" "${response_file}" || result=1; - # Some services return 40x code until they are ready, so let's give them - # some chance and not end with failure right away - # Do not wait if we already have expected outcome though - if [ "${result}" -eq 0 ] || [ "${attempt}" -gt "${ignore_error_attempts}" ] || [ "${attempt}" -eq "${max_attempts}" ] ; then - break - fi - fi - attempt=$(( attempt + 1 )) - sleep "${sleep_time}" - done - rm -f "${response_file}" - return "${result}" -} - -# ct_os_get_image_from_pod -# ------------------------ -# Print image identifier from an existing pod to stdout -# Argument: pod_prefix - prefix or full name of the pod to get image from -ct_os_get_image_from_pod() { - local pod_prefix=$1 ; shift - local pod_name - pod_name=$(ct_os_get_pod_name "$pod_prefix") - oc get "po/${pod_name}" -o yaml | sed -ne 's/^\s*image:\s*\(.*\)\s*$/\1/ p' | head -1 -} - -# ct_os_check_cmd_internal -# ---------------- -# Runs a specified command, checks exit code and compares the output with expected regexp. -# That all is done inside an image in the cluster, so the function is used -# typically in clusters that are not accessible outside. -# The check is repeated until timeout. -# Argument: util_image_name - name of the image in the cluster that is used for running the cmd -# Argument: service_name - kubernetes' service name to work with (IP address is taken from this one) -# Argument: check_command - command that is run within the util_image_name container -# Argument: expected_content_match - regexp that must be in the output (use .* to ignore check) -# Argument: timeout - number of seconds to wait till the check succeeds -function ct_os_check_cmd_internal() { - local util_image_name=$1 ; shift - local service_name=$1 ; shift - local check_command=$1 ; shift - local expected_content_match=${1:-.*} ; shift - local timeout=${1:-60} ; shift || : - - : " Service ${service_name} check ..." - - local output - local ret - local ip - local check_command_exp - - ip=$(ct_os_get_service_ip "${service_name}") - # shellcheck disable=SC2001 - check_command_exp=$(echo "$check_command" | sed -e "s//$ip/g") - - ct_os_deploy_cmd_image "$(ct_os_get_image_from_pod "${util_image_name##*/}" | head -n 1)" - SECONDS=0 - - echo -n "Waiting for ${service_name} service becoming ready ..." - while true ; do - output=$(ct_os_cmd_image_run "$check_command_exp") - ret=$? - echo "${output}" | grep -qe "${expected_content_match}" || ret=1 - if [ ${ret} -eq 0 ] ; then - echo " PASS" - return 0 - fi - echo -n "." - [ ${SECONDS} -gt "${timeout}" ] && break - sleep 3 - done - echo " FAIL" - return 1 -} - -# vim: set tabstop=2:shiftwidth=2:expandtab: diff --git a/common/test-lib.sh b/common/test-lib.sh deleted file mode 100644 index b959c34..0000000 --- a/common/test-lib.sh +++ /dev/null @@ -1,653 +0,0 @@ -# shellcheck shell=bash -# -# Test a container image. -# -# Always use sourced from a specific container testfile -# -# reguires definition of CID_FILE_DIR -# CID_FILE_DIR=$(mktemp --suffix=_test_cidfiles -d) -# reguires definition of TEST_LIST -# TEST_LIST="\ -# ctest_container_creation -# ctest_doc_content" - -# Container CI tests -# abbreviated as "ct" - -# may be redefined in the specific container testfile -EXPECTED_EXIT_CODE=0 - -# ct_cleanup -# -------------------- -# Cleans up containers used during tests. Stops and removes all containers -# referenced by cid_files in CID_FILE_DIR. Dumps logs if a container exited -# unexpectedly. Removes the cid_files and CID_FILE_DIR as well. -# Uses: $CID_FILE_DIR - path to directory containing cid_files -# Uses: $EXPECTED_EXIT_CODE - expected container exit code -function ct_cleanup() { - for cid_file in "$CID_FILE_DIR"/* ; do - local container - container=$(cat "$cid_file") - - : "Stopping and removing container $container..." - docker stop "$container" - exit_status=$(docker inspect -f '{{.State.ExitCode}}' "$container") - if [ "$exit_status" != "$EXPECTED_EXIT_CODE" ]; then - : "Dumping logs for $container" - docker logs "$container" - fi - docker rm -v "$container" - rm "$cid_file" - done - rmdir "$CID_FILE_DIR" - : "Done." -} - -# ct_enable_cleanup -# -------------------- -# Enables automatic container cleanup after tests. -function ct_enable_cleanup() { - trap ct_cleanup EXIT SIGINT -} - -# ct_get_cid [name] -# -------------------- -# Prints container id from cid_file based on the name of the file. -# Argument: name - name of cid_file where the container id will be stored -# Uses: $CID_FILE_DIR - path to directory containing cid_files -function ct_get_cid() { - local name="$1" ; shift || return 1 - cat "$CID_FILE_DIR/$name" -} - -# ct_get_cip [id] -# -------------------- -# Prints container ip address based on the container id. -# Argument: id - container id -function ct_get_cip() { - local id="$1" ; shift - docker inspect --format='{{.NetworkSettings.IPAddress}}' "$(ct_get_cid "$id")" -} - -# ct_wait_for_cid [cid_file] -# -------------------- -# Holds the execution until the cid_file is created. Usually run after container -# creation. -# Argument: cid_file - name of the cid_file that should be created -function ct_wait_for_cid() { - local cid_file=$1 - local max_attempts=10 - local sleep_time=1 - local attempt=1 - local result=1 - while [ $attempt -le $max_attempts ]; do - [ -f "$cid_file" ] && [ -s "$cid_file" ] && return 0 - : "Waiting for container start..." - attempt=$(( attempt + 1 )) - sleep $sleep_time - done - return 1 -} - -# ct_assert_container_creation_fails [container_args] -# -------------------- -# The invocation of docker run should fail based on invalid container_args -# passed to the function. Returns 0 when container fails to start properly. -# Argument: container_args - all arguments are passed directly to dokcer run -# Uses: $CID_FILE_DIR - path to directory containing cid_files -function ct_assert_container_creation_fails() { - local ret=0 - local max_attempts=10 - local attempt=1 - local cid_file=assert - set +e - local old_container_args="${CONTAINER_ARGS-}" - # we really work with CONTAINER_ARGS as with a string - # shellcheck disable=SC2124 - CONTAINER_ARGS="$@" - if ct_create_container "$cid_file" ; then - local cid - cid=$(ct_get_cid "$cid_file") - - while [ "$(docker inspect -f '{{.State.Running}}' "$cid")" == "true" ] ; do - sleep 2 - attempt=$(( attempt + 1 )) - if [ "$attempt" -gt "$max_attempts" ]; then - docker stop "$cid" - ret=1 - break - fi - done - exit_status=$(docker inspect -f '{{.State.ExitCode}}' "$cid") - if [ "$exit_status" == "0" ]; then - ret=1 - fi - docker rm -v "$cid" - rm "$CID_FILE_DIR/$cid_file" - fi - [ -n "$old_container_args" ] && CONTAINER_ARGS="$old_container_args" - set -e - return "$ret" -} - -# ct_create_container [name, command] -# -------------------- -# Creates a container using the IMAGE_NAME and CONTAINER_ARGS variables. Also -# stores the container id to a cid_file located in the CID_FILE_DIR, and waits -# for the creation of the file. -# Argument: name - name of cid_file where the container id will be stored -# Argument: command - optional command to be executed in the container -# Uses: $CID_FILE_DIR - path to directory containing cid_files -# Uses: $CONTAINER_ARGS - optional arguments passed directly to docker run -# Uses: $IMAGE_NAME - name of the image being tested -function ct_create_container() { - local cid_file="$CID_FILE_DIR/$1" ; shift - # create container with a cidfile in a directory for cleanup - # shellcheck disable=SC2086 - docker run --cidfile="$cid_file" -d ${CONTAINER_ARGS:-} "$IMAGE_NAME" "$@" - ct_wait_for_cid "$cid_file" || return 1 - : "Created container $(cat "$cid_file")" -} - -# ct_scl_usage_old [name, command, expected] -# -------------------- -# Tests three ways of running the SCL, by looking for an expected string -# in the output of the command -# Argument: name - name of cid_file where the container id will be stored -# Argument: command - executed inside the container -# Argument: expected - string that is expected to be in the command output -# Uses: $CID_FILE_DIR - path to directory containing cid_files -# Uses: $IMAGE_NAME - name of the image being tested -function ct_scl_usage_old() { - local name="$1" - local command="$2" - local expected="$3" - local out="" - : " Testing the image SCL enable" - out=$(docker run --rm "${IMAGE_NAME}" /bin/bash -c "${command}") - if ! echo "${out}" | grep -q "${expected}"; then - echo "ERROR[/bin/bash -c \"${command}\"] Expected '${expected}', got '${out}'" >&2 - return 1 - fi - out=$(docker exec "$(ct_get_cid "$name")" /bin/bash -c "${command}" 2>&1) - if ! echo "${out}" | grep -q "${expected}"; then - echo "ERROR[exec /bin/bash -c \"${command}\"] Expected '${expected}', got '${out}'" >&2 - return 1 - fi - out=$(docker exec "$(ct_get_cid "$name")" /bin/sh -ic "${command}" 2>&1) - if ! echo "${out}" | grep -q "${expected}"; then - echo "ERROR[exec /bin/sh -ic \"${command}\"] Expected '${expected}', got '${out}'" >&2 - return 1 - fi -} - -# ct_doc_content_old [strings] -# -------------------- -# Looks for occurence of stirngs in the documentation files and checks -# the format of the files. Files examined: help.1 -# Argument: strings - strings expected to appear in the documentation -# Uses: $IMAGE_NAME - name of the image being tested -function ct_doc_content_old() { - local tmpdir - tmpdir=$(mktemp -d) - local f - : " Testing documentation in the container image" - # Extract the help files from the container - # shellcheck disable=SC2043 - for f in help.1 ; do - docker run --rm "${IMAGE_NAME}" /bin/bash -c "cat /${f}" >"${tmpdir}/$(basename "${f}")" - # Check whether the files contain some important information - for term in "$@" ; do - if ! grep -F -q -e "${term}" "${tmpdir}/$(basename "${f}")" ; then - echo "ERROR: File /${f} does not include '${term}'." >&2 - return 1 - fi - done - # Check whether the files use the correct format - for term in TH PP SH ; do - if ! grep -q "^\.${term}" "${tmpdir}/help.1" ; then - echo "ERROR: /help.1 is probably not in troff or groff format, since '${term}' is missing." >&2 - return 1 - fi - done - done - : " 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 -# -------------------- -# Checks existance of the npm tool and runs it. -function ct_npm_works() { - local tmpdir - tmpdir=$(mktemp -d) - : " Testing npm in the container image" - local cid_file="${tmpdir}/cid" - if ! docker run --rm "${IMAGE_NAME}" /bin/bash -c "npm --version" >"${tmpdir}/version" ; then - echo "ERROR: 'npm --version' does not work inside the image ${IMAGE_NAME}." >&2 - return 1 - fi - - # shellcheck disable=SC2046 - 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 - - if ! docker exec "$(cat "$cid_file")" /bin/bash -c "npm --verbose install jquery && test -f node_modules/jquery/src/jquery.js" >"${tmpdir}/jquery" 2>&1 ; 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 -# of colon-separated list of directories. -ct_path_append () -{ - if eval "test -n \"\${$1-}\""; then - eval "$1=\$2:\$$1" - else - eval "$1=\$2" - fi -} - - -# ct_path_foreach PATH ACTION [ARGS ...] -# -------------------------------------- -# For each DIR in PATH execute ACTION (path is colon separated list of -# directories). The particular calls to ACTION will look like -# '$ ACTION directory [ARGS ...]' -ct_path_foreach () -{ - local dir dirlist action save_IFS - save_IFS=$IFS - IFS=: - dirlist=$1 - action=$2 - shift 2 - for dir in $dirlist; do "$action" "$dir" "$@" ; done - IFS=$save_IFS -} - - -# ct_run_test_list -# -------------------- -# Execute the tests specified by TEST_LIST -# Uses: $TEST_LIST - list of test names -function ct_run_test_list() { - for test_case in $TEST_LIST; do - : "Running test $test_case" - # shellcheck source=/dev/null - [ -f "test/$test_case" ] && source "test/$test_case" - # shellcheck source=/dev/null - [ -f "../test/$test_case" ] && source "../test/$test_case" - $test_case - done; -} - -# ct_gen_self_signed_cert_pem -# --------------------------- -# Generates a self-signed PEM certificate pair into specified directory. -# Argument: output_dir - output directory path -# Argument: base_name - base name of the certificate files -# Resulted files will be those: -# /-cert-selfsigned.pem -- public PEM cert -# /-key.pem -- PEM private key -ct_gen_self_signed_cert_pem() { - local output_dir=$1 ; shift - local base_name=$1 ; shift - mkdir -p "${output_dir}" - openssl req -newkey rsa:2048 -nodes -keyout "${output_dir}"/"${base_name}"-key.pem -subj '/C=GB/ST=Berkshire/L=Newbury/O=My Server Company' > "${base_name}"-req.pem - openssl req -new -x509 -nodes -key "${output_dir}"/"${base_name}"-key.pem -batch > "${output_dir}"/"${base_name}"-cert-selfsigned.pem -} - -# ct_obtain_input FILE|DIR|URL -# -------------------- -# Either copies a file or a directory to a tmp location for local copies, or -# downloads the file from remote location. -# Resulted file path is printed, so it can be later used by calling function. -# Arguments: input - local file, directory or remote URL -function ct_obtain_input() { - local input=$1 - local extension="${input##*.}" - - # Try to use same extension for the temporary file if possible - [[ "${extension}" =~ ^[a-z0-9]*$ ]] && extension=".${extension}" || extension="" - - local output - output=$(mktemp "/var/tmp/test-input-XXXXXX$extension") - if [ -f "${input}" ] ; then - cp -f "${input}" "${output}" - elif [ -d "${input}" ] ; then - rm -f "${output}" - cp -r -LH "${input}" "${output}" - elif echo "${input}" | grep -qe '^http\(s\)\?://' ; then - curl "${input}" > "${output}" - else - echo "ERROR: file type not known: ${input}" >&2 - return 1 - fi - echo "${output}" -} - -# ct_test_response -# ---------------- -# Perform GET request to the application container, checks output with -# a reg-exp and HTTP response code. -# Argument: url - request URL path -# Argument: expected_code - expected HTTP response code -# Argument: body_regexp - PCRE regular expression that must match the response body -# Argument: max_attempts - Optional number of attempts (default: 20), three seconds sleep between -# Argument: ignore_error_attempts - Optional number of attempts when we ignore error output (default: 10) -ct_test_response() { - local url="$1" - local expected_code="$2" - local body_regexp="$3" - local max_attempts=${4:-20} - local ignore_error_attempts=${5:-10} - - : " Testing the HTTP(S) response for <${url}>" - local sleep_time=3 - local attempt=1 - local result=1 - local status - local response_code - local response_file - response_file=$(mktemp /tmp/ct_test_response_XXXXXX) - while [ "${attempt}" -le "${max_attempts}" ]; do - curl --connect-timeout 10 -s -w '%{http_code}' "${url}" >"${response_file}" && status=0 || status=1 - if [ "${status}" -eq 0 ]; then - response_code=$(tail -c 3 "${response_file}") - if [ "${response_code}" -eq "${expected_code}" ]; then - result=0 - fi - grep -qP -e "${body_regexp}" "${response_file}" || result=1; - # Some services return 40x code until they are ready, so let's give them - # some chance and not end with failure right away - # Do not wait if we already have expected outcome though - if [ "${result}" -eq 0 ] || [ "${attempt}" -gt "${ignore_error_attempts}" ] || [ "${attempt}" -eq "${max_attempts}" ] ; then - break - fi - fi - attempt=$(( attempt + 1 )) - sleep "${sleep_time}" - done - rm -f "${response_file}" - return "${result}" -} - -# ct_registry_from_os OS -# ---------------- -# Transform operating system string [os] into registry url -# Argument: OS - string containing the os version -ct_registry_from_os() { - local registry="" - case $1 in - rhel*) - registry=registry.redhat.io - ;; - *) - registry=docker.io - ;; - esac - echo "$registry" -} - - # ct_get_public_image_name OS BASE_IMAGE_NAME VERSION -# ---------------- -# Transform the arguments into public image name -# Argument: OS - string containing the os version -# Argument: BASE_IMAGE_NAME - string containing the base name of the image as defined in the Makefile -# Argument: VERSION - string containing the version of the image as defined in the Makefile -ct_get_public_image_name() { - local os=$1; shift - local base_image_name=$1; shift - local version=$1; shift - - local public_image_name - local registry - - registry=$(ct_registry_from_os "$os") - if [ "x$os" == "xrhel7" ]; then - public_image_name=$registry/rhscl/$base_image_name-${version//./}-rhel7 - elif [ "x$os" == "xrhel8" ]; then - public_image_name=$registry/rhel8/$base_image_name-${version//./} - elif [ "x$os" == "xcentos7" ]; then - public_image_name=$registry/centos/$base_image_name-${version//./}-centos7 - fi - - echo "$public_image_name" -} - -# ct_assert_cmd_success CMD -# ---------------- -# Evaluates [cmd] and fails if it does not succeed. -# Argument: CMD - Command to be run -function ct_assert_cmd_success() { - echo "Checking '$*' for success ..." - if ! eval "$@" &>/dev/null; then - echo " FAIL" - return 1 - fi - echo " PASS" - return 0 -} - -# ct_assert_cmd_failure CMD -# ---------------- -# Evaluates [cmd] and fails if it succeeds. -# Argument: CMD - Command to be run -function ct_assert_cmd_failure() { - echo "Checking '$*' for failure ..." - if eval "$@" &>/dev/null; then - echo " FAIL" - return 1 - fi - echo " PASS" - return 0 -} - - -# ct_random_string [LENGTH=10] -# ---------------------------- -# Generate pseudorandom alphanumeric string of LENGTH bytes, the -# default length is 10. The string is printed on stdout. -ct_random_string() -( - export LC_ALL=C - dd if=/dev/urandom count=1 bs=10k 2>/dev/null \ - | tr -dc 'a-z0-9' \ - | fold -w "${1-10}" \ - | head -n 1 -) - -# ct_s2i_usage IMG_NAME [S2I_ARGS] -# ---------------------------- -# Create a container and run the usage script inside -# Argument: IMG_NAME - name of the image to be used for the container run -# Argument: S2I_ARGS - Additional list of source-to-image arguments, currently unused. -ct_s2i_usage() -{ - local img_name=$1; shift - local s2i_args="$*"; - local usage_command="/usr/libexec/s2i/usage" - docker run --rm "$img_name" bash -c "$usage_command" -} - -# ct_s2i_build_as_df APP_PATH SRC_IMAGE DST_IMAGE [S2I_ARGS] -# ---------------------------- -# Create a new s2i app image from local sources in a similar way as source-to-image would have used. -# 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. -# Only used to check for pull-policy=never and environment variable definitions. -ct_s2i_build_as_df() -{ - local app_path=$1; shift - local src_image=$1; shift - local dst_image=$1; shift - local s2i_args="$*"; - local local_app=upload/src/ - local local_scripts=upload/scripts/ - 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) - 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=$(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 <"$df_name" -FROM $src_image -LABEL "io.openshift.s2i.build.image"="$src_image" \\ - "io.openshift.s2i.build.source-location"="$app_path" -USER root -COPY $local_app /tmp/src -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 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" - echo "ADD artifacts.tar /tmp/artifacts" - 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 - echo "RUN /tmp/scripts/assemble" >>"$df_name" - else - echo "RUN /usr/libexec/s2i/assemble" >>"$df_name" - fi - # If exists, set the custom run script as CMD, else default to /usr/libexec/s2i/run - if [ -x "$local_scripts/run" ]; then - echo "CMD /tmp/scripts/run" >>"$df_name" - 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 - # shellcheck disable=SC2086 - docker build $mount_options -f "$df_name" --no-cache=true -t "$dst_image" . - ) -} - -# ct_check_image_availability PUBLIC_IMAGE_NAME -# ---------------------------- -# Pull an image from the public repositories to see if the image is already available. -# Argument: PUBLIC_IMAGE_NAME - string containing the public name of the image to pull -ct_check_image_availability() { - local public_image_name=$1; - - # Try pulling the image to see if it is accessible - if ! docker pull "$public_image_name" &>/dev/null; then - echo "$public_image_name could not be downloaded via 'docker'" - return 1 - fi -} - -# vim: set tabstop=2:shiftwidth=2:expandtab: diff --git a/common/test-remote-cluster.sh b/common/test-remote-cluster.sh deleted file mode 100755 index f030663..0000000 --- a/common/test-remote-cluster.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash - -# This script is used to test container images integrated in the OpenShift. -# -# VERSIONS - Must be set to a list with possible versions (subdirectories) -# -# This script expects oc command to exist and logged in to a working cluster. - -set -e - -export OS=${OS:-rhel7} - -if [ "${OS}" == "rhel7" ] ; then - NAMESPACE=${NAMESPACE:-rhscl/} - REGISTRY=${REGISTRY:-registry.access.redhat.com/} -else - NAMESPACE=${NAMESPACE:-centos/} -fi - -export NAMESPACE -export REGISTRY - -for dir in ${VERSIONS}; do - pushd "${dir}" > /dev/null - - export IMAGE_NAME="${REGISTRY}${NAMESPACE}${BASE_IMAGE_NAME}-${dir//./}-${OS}" - - VERSION=$dir test/run-openshift-remote-cluster - - popd > /dev/null -done - -# vim: set tabstop=2:shiftwidth=2:expandtab: diff --git a/common/test.sh b/common/test.sh deleted file mode 100755 index 7d2abc6..0000000 --- a/common/test.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/bash - -# This script is used to test the OpenShift Docker images. -# -# TEST_MODE - If set, run regular test suite -# TEST_OPENSHIFT_MODE - If set, run OpenShift tests (if present) -# VERSIONS - Must be set to a list with possible versions (subdirectories) - -set -e - -for dir in ${VERSIONS}; do - [ ! -e "${dir}/.image-id" ] && echo "-> Image for version $dir not built, skipping tests." && continue - pushd "${dir}" > /dev/null - IMAGE_ID=$(cat .image-id) - export IMAGE_ID - # Kept also IMAGE_NAME as some tests might still use that. - IMAGE_NAME=$(docker inspect -f "{{.Config.Labels.name}}" "$IMAGE_ID") - export IMAGE_NAME - - if [ -n "${TEST_MODE}" ]; then - VERSION=$dir test/run - fi - - if [ -n "${TEST_CONU_MODE}" ]; then - if [[ -x test/run-conu ]]; then - if [ -n "${CONU_IMAGE}" ]; then - echo "-> Running conu tests in a container" - docker run \ - --net=host \ - -e VERSION="${dir}" \ - -e IMAGE_NAME \ - --rm \ - --security-opt label=disable \ - -ti \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v "${PWD}"/../:/src \ - -w "/src/${dir}/" \ - -ti \ - "${CONU_IMAGE}" \ - ./test/run-conu - else - VERSION="${dir}" ./test/run-conu - fi - else - echo "-> conu tests are not present, skipping" - fi - fi - - if [ -n "${TEST_OPENSHIFT_MODE}" ]; then - if [[ -x test/run-openshift ]]; then - VERSION=$dir test/run-openshift - else - echo "-> OpenShift tests are not present, skipping" - fi - fi - - popd > /dev/null -done diff --git a/common/tests/.gitignore b/common/tests/.gitignore deleted file mode 100644 index 964e2de..0000000 --- a/common/tests/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.image-id* -help.1 diff --git a/common/tests/failures/check/Makefile b/common/tests/failures/check/Makefile deleted file mode 100644 index 6d41a15..0000000 --- a/common/tests/failures/check/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -# Variables are documented in common/build.sh. -BASE_IMAGE_NAME = test-container -VERSIONS = v0 -include common/common.mk diff --git a/common/tests/failures/check/common b/common/tests/failures/check/common deleted file mode 120000 index a8a4f8c..0000000 --- a/common/tests/failures/check/common +++ /dev/null @@ -1 +0,0 @@ -../../.. \ No newline at end of file diff --git a/common/tests/failures/check/v0/Dockerfile b/common/tests/failures/check/v0/Dockerfile deleted file mode 100644 index 76421aa..0000000 --- a/common/tests/failures/check/v0/Dockerfile +++ /dev/null @@ -1,2 +0,0 @@ -FROM centos/s2i-core-centos7 -LABEL name=test-image diff --git a/common/tests/failures/check/v0/README.md b/common/tests/failures/check/v0/README.md deleted file mode 100644 index 19fd6ae..0000000 --- a/common/tests/failures/check/v0/README.md +++ /dev/null @@ -1 +0,0 @@ -This is just no-op-build container. diff --git a/common/tests/failures/check/v0/test/run b/common/tests/failures/check/v0/test/run deleted file mode 100755 index 1dace69..0000000 --- a/common/tests/failures/check/v0/test/run +++ /dev/null @@ -1,3 +0,0 @@ -#! /bin/sh -x - -false this must fail the whole testsuite diff --git a/common/tests/remote-containers.sh b/common/tests/remote-containers.sh deleted file mode 100755 index b87ebff..0000000 --- a/common/tests/remote-containers.sh +++ /dev/null @@ -1,103 +0,0 @@ -#! /bin/bash - -set -e - -declare -A IMAGES - -for image in ${TESTED_IMAGES}; do - IMAGES[$image]=master -done - -OS=centos7 - -MERGE_INTO=origin/master - -# This is the Fedora default, some users' boxes have more strict -# defaults (e.g. 0077). -umask 0022 - -die () { echo >&2 " # FATAL: $*"; exit 1; } -info () { echo " * $*"; } -error () { echo >&2 " # ERROR: $*"; } - -test -f common.mk -a -f build.sh -a -d .git \ - || die "Doesn't seem to be run from common's git directory" - -analyse_commits () -{ - # TODO: If we wanted to test "after PR merge", this needs to take some - # argument specifying how long we should look in the commit history. - git merge-base --is-ancestor "$MERGE_INTO" HEAD \ - || die "Please rebase the commit '$(git rev-parse --short HEAD)'" \ - "to allow --ff merge into '$MERGE_INTO' branch" - - while read line; do - case $line in - Required-by:\ *) - set -- $line - old_IFS=$IFS - IFS=\# - set -- $2 - IFS=$old_IFS - set -- $1 $2 - info "PR commits ask for testing $1 from PR $2" - IMAGES[$1]=$2 - ;; - esac - done < <(git log --format=%B --reverse "$MERGE_INTO"..HEAD) -} - -analyse_commits - -for image in "${!IMAGES[@]}"; do - # We don't want to remove user's WIP stuff. - test -e "$image" && die "directory '$image' exists" - - ( set -e - testdir=$PWD - cleanup () { - set -x - # Ensure the cleanup finishes! - trap '' INT - # Go back, wherever we are. - cd "$testdir" - # Try to cleanup, if available (and if needed). - make clean -C "$image" || : - # Drop the image sources. - test ! -d "$image" || rm -rf "$image" - } - trap cleanup EXIT - - info "Testing $image image" - - # Use --recursive even if we remove 'common', because there might be - # other git submodules which need to be tested. - git clone --recursive -q https://github.com/sclorg/"$image".git - cd "$image" - - revision=${IMAGES[$image]} - if ! test "$revision" = master; then - info "Fetching $image PR $revision" - git fetch origin "pull/$revision/head":PR_BRANCH - git checkout PR_BRANCH - git submodule update - fi - - # We fail if the 'common' directory doesn't exist. - test -d common - rm -rf common - info "Replacing common with PR's version" - ln -s ../ common - - # TODO: Do we have to test all $(VERSION)s? - # TODO: The PS4 hack doesn't work if we run the testsuite as UID=0. - PS4="+ [$image] " make TARGET="$OS" test - - # Cleanup. - make clean - ) - - if test $? -ne 0; then - die "Tests for $image failed" - fi -done diff --git a/common/tests/squash/.gitignore b/common/tests/squash/.gitignore deleted file mode 100644 index 9414382..0000000 --- a/common/tests/squash/.gitignore +++ /dev/null @@ -1 +0,0 @@ -Dockerfile diff --git a/common/tests/squash/squash.sh b/common/tests/squash/squash.sh deleted file mode 100755 index 4393d55..0000000 --- a/common/tests/squash/squash.sh +++ /dev/null @@ -1,24 +0,0 @@ -#! /bin/sh - -set -e - -if grep -q "Red Hat Enterprise Linux release 8" /etc/system-release; then - # No use testing squash.py on rhel8 for now as it does not work at all - echo " ! test case ignored on RHEL8 host" - exit 0 -fi - -origin=busybox -squash=$(dirname "$(readlink -f "$0")")/../../squash.py -cd "$(dirname "$0")" - -cat > Dockerfile < /bin/bash - -.fi -.RE - -.PP -After you Podman exec -\[la]https://github.com/containers/libpod\[ra] into the running container, your current directory is set to \fB\fC/opt/app\-root/src\fR, where the source code for your application is located. - -.SS Using OpenShift's rsync -.PP -If you have deployed the container to OpenShift, you can use oc rsync -\[la]https://docs.openshift.org/latest/dev_guide/copy_files_to_container.html\[ra] to copy local files to a remote container running in an OpenShift pod. - -.SS Warning: -.PP -The default behaviour of the s2i\-nodejs container image is to run the Node.js application using the command \fB\fCnpm start\fR\&. This runs the \fIstart\fP script in the \fIpackage.json\fP file. In developer mode, the application is run using the command \fB\fCnodemon\fR\&. The default behaviour of nodemon is to look for the \fImain\fP attribute in the \fIpackage.json\fP file, and execute that script. If the \fImain\fP attribute doesn't appear in the \fIpackage.json\fP file, it executes the \fIstart\fP script. So, in order to achieve some sort of uniform functionality between production and development modes, the user should remove the \fImain\fP attribute. - -.PP -Below is an example \fIpackage.json\fP file with the \fImain\fP attribute and \fIstart\fP script marked appropriately: - -.PP -.RS - -.nf -{ - "name": "node\-echo", - "version": "0.0.1", - "description": "node\-echo", - "main": "example.js", <\-\-\- main attribute - "dependencies": { - }, - "devDependencies": { - "nodemon": "*" - }, - "engine": { - "node": "*", - "npm": "*" - }, - "scripts": { - "dev": "nodemon \-\-ignore node\_modules/ server.js", - "start": "node server.js" <\-\- start script - }, - "keywords": [ - "Echo" - ], - "license": "", -} - -.fi -.RE - -.SS Note: -.PP -\fB\fCoc rsync\fR is only available in versions 3.1+ of OpenShift. - -.SH See also -.PP -Dockerfile and other sources are available on -\[la]https://github.com/sclorg/s2i-nodejs-container\[ra]\&. -In that repository you also can find another versions of Python environment Dockerfiles. -Dockerfile for CentOS is called \fB\fCDockerfile\fR, Dockerfile for RHEL7 is called \fB\fCDockerfile.rhel7\fR, -for RHEL8 it's \fB\fCDockerfile.rhel8\fR and the Fedora Dockerfile is called Dockerfile.fedora. diff --git a/root/opt/app-root/etc/generate_container_user b/root/opt/app-root/etc/generate_container_user deleted file mode 100644 index b28a7a3..0000000 --- a/root/opt/app-root/etc/generate_container_user +++ /dev/null @@ -1,17 +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}:/sbin/nologin" >> $NSS_WRAPPER_PASSWD - - export NSS_WRAPPER_PASSWD - export NSS_WRAPPER_GROUP - export LD_PRELOAD=libnss_wrapper.so -fi diff --git a/root/opt/app-root/etc/npm_global_module_list b/root/opt/app-root/etc/npm_global_module_list deleted file mode 100644 index 005e150..0000000 --- a/root/opt/app-root/etc/npm_global_module_list +++ /dev/null @@ -1,5 +0,0 @@ -async -mime -mkdirp -qs -minimatch diff --git a/root/opt/app-root/etc/scl_enable b/root/opt/app-root/etc/scl_enable deleted file mode 100644 index 4bfebea..0000000 --- a/root/opt/app-root/etc/scl_enable +++ /dev/null @@ -1,3 +0,0 @@ -# This will make scl collection binaries work out of box. -unset BASH_ENV PROMPT_COMMAND ENV -source scl_source enable rh-nodejs${NODEJS_VERSION} diff --git a/s2i/bin/assemble b/s2i/bin/assemble deleted file mode 100755 index 78c9b97..0000000 --- a/s2i/bin/assemble +++ /dev/null @@ -1,116 +0,0 @@ -#!/bin/bash - -# Prevent running assemble in builders different than official STI image. -# The official nodejs:8-onbuild already run npm install and use different -# application folder. -[ -d "/usr/src/app" ] && exit 0 - -set -e - -# FIXME: Linking of global modules is disabled for now as it causes npm failures -# under RHEL7 -# Global modules good to have -# npmgl=$(grep "^\s*[^#\s]" ../etc/npm_global_module_list | sort -u) -# Available global modules; only match top-level npm packages -#global_modules=$(npm ls -g 2> /dev/null | perl -ne 'print "$1\n" if /^\S+\s(\S+)\@[\d\.-]+/' | sort -u) -# List all modules in common -#module_list=$(/usr/bin/comm -12 <(echo "${global_modules}") | tr '\n' ' ') -# Link the modules -#npm link $module_list - -safeLogging () { - if [[ $1 =~ http[s]?://.*@.*$ ]]; then - echo $1 | sed 's/^.*@/redacted@/' - else - echo $1 - fi -} - -shopt -s dotglob -if [ -d /tmp/artifacts ] && [ "$(ls /tmp/artifacts/ 2>/dev/null)" ]; then - echo "---> Restoring previous build artifacts ..." - mv -T --verbose /tmp/artifacts/node_modules "${HOME}/node_modules" -fi - -echo "---> Installing application source ..." -mv /tmp/src/* ./ - -# Fix source directory permissions -fix-permissions ./ - -if [ ! -z $HTTP_PROXY ]; then - echo "---> Setting npm http proxy to" $(safeLogging $HTTP_PROXY) - npm config set proxy $HTTP_PROXY -fi - -if [ ! -z $http_proxy ]; then - echo "---> Setting npm http proxy to" $(safeLogging $http_proxy) - npm config set proxy $http_proxy -fi - -if [ ! -z $HTTPS_PROXY ]; then - echo "---> Setting npm https proxy to" $(safeLogging $HTTPS_PROXY) - npm config set https-proxy $HTTPS_PROXY -fi - -if [ ! -z $https_proxy ]; then - echo "---> Setting npm https proxy to" $(safeLogging $https_proxy) - npm config set https-proxy $https_proxy -fi - -# Change the npm registry mirror if provided -if [ -n "$NPM_MIRROR" ]; then - npm config set registry $NPM_MIRROR -fi - -# Set the DEV_MODE to false by default. -if [ -z "$DEV_MODE" ]; then - export DEV_MODE=false -fi - -# If NODE_ENV is not set by the user, then NODE_ENV is determined by whether -# the container is run in development mode. -if [ -z "$NODE_ENV" ]; then - if [ "$DEV_MODE" == true ]; then - export NODE_ENV=development - else - export NODE_ENV=production - fi -fi - -if [ "$NODE_ENV" != "production" ]; then - - echo "---> Building your Node application from source" - npm install - -else - - echo "---> Installing all dependencies" - NODE_ENV=development npm install - - #do not fail when there is no build script - echo "---> Building in production mode" - npm run build --if-present - - echo "---> Pruning the development dependencies" - npm prune - - # Clear the npm's cache and tmp directories only if they are not a docker volumes - NPM_CACHE=$(npm config get cache) - if ! mountpoint $NPM_CACHE; then - echo "---> Cleaning the npm cache $NPM_CACHE" - #As of npm@5 even the 'npm cache clean --force' does not fully remove the cache directory - # instead of $NPM_CACHE* use $NPM_CACHE/*. - # We do not want to delete .npmrc file. - rm -rf "${NPM_CACHE:?}/" - fi - NPM_TMP=$(npm config get tmp) - if ! mountpoint $NPM_TMP; then - echo "---> Cleaning the $NPM_TMP/npm-*" - rm -rf $NPM_TMP/npm-* - fi - -fi - -# Fix source directory permissions -fix-permissions ./ diff --git a/s2i/bin/run b/s2i/bin/run deleted file mode 100755 index ff566f5..0000000 --- a/s2i/bin/run +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/bash - -# S2I run script for the 'nodejs' image. -# The run script executes the server that runs your application. -# -# For more information see the documentation: -# https://github.com/openshift/source-to-image/blob/master/docs/builder_image.md -# - -set -e - -if [ -e "/opt/app-root/etc/generate_container_user" ]; then - source /opt/app-root/etc/generate_container_user -fi - -# Runs the nodejs application server. If the container is run in development mode, -# hot deploy and debugging are enabled. -run_node() { - echo -e "Environment: \n\tDEV_MODE=${DEV_MODE}\n\tNODE_ENV=${NODE_ENV}\n\tDEBUG_PORT=${DEBUG_PORT}" - if [ "$DEV_MODE" == true ]; then - echo "Launching via nodemon..." - exec nodemon --inspect="$DEBUG_PORT" - else - echo "Launching via npm..." - exec npm run -d $NPM_RUN - fi -} - -#Set the debug port to 5858 by default. -if [ -z "$DEBUG_PORT" ]; then - export DEBUG_PORT=5858 -fi - -# Set the environment to development by default. -if [ -z "$DEV_MODE" ]; then - export DEV_MODE=false -fi - -# If NODE_ENV is not set by the user, then NODE_ENV is determined by whether -# the container is run in development mode. -if [ -z "$NODE_ENV" ]; then - if [ "$DEV_MODE" == true ]; then - export NODE_ENV=development - else - export NODE_ENV=production - fi -fi - -# If the official dockerhub node image is used, skip the SCL setup below -# and just run the nodejs server -if [ -d "/usr/src/app" ]; then - run_node -fi - -# Allow users to inspect/debug the builder image itself, by using: -# $ docker run -i -t openshift/centos-nodejs-builder --debug -# -[ "$1" == "--debug" ] && exec /bin/bash - -run_node diff --git a/s2i/bin/save-artifacts b/s2i/bin/save-artifacts deleted file mode 100755 index 16be05e..0000000 --- a/s2i/bin/save-artifacts +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -if [ -d "${HOME}/node_modules" ] && [ "$(ls "${HOME}/node_modules" 2>/dev/null)" ]; then - tar -C "${HOME}" -cf - node_modules -fi diff --git a/s2i/bin/usage b/s2i/bin/usage deleted file mode 100755 index cf00805..0000000 --- a/s2i/bin/usage +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -DISTRO=`cat /etc/*-release | grep ^ID= | grep -Po '".*?"' | tr -d '"'` - -cat </dev/null -} - -container_exists() { - image_exists $(cat $cid_file) -} - -container_ip() { - docker inspect --format="{{ .NetworkSettings.IPAddress }}" $(cat $cid_file) -} - -container_logs() { - docker logs $(cat $cid_file) -} - -run_s2i_build() { - ct_s2i_build_as_df file://${test_dir}/test-app ${IMAGE_NAME} ${IMAGE_NAME}-testapp ${s2i_args} $(ct_build_s2i_npm_variables) $1 -} - -run_s2i_build_proxy() { - ct_s2i_build_as_df file://${test_dir}/test-hw ${IMAGE_NAME} ${IMAGE_NAME}-testhw ${s2i_args} $(ct_build_s2i_npm_variables) -e HTTP_PROXY=$1 -e http_proxy=$1 -e HTTPS_PROXY=$2 -e https_proxy=$2 -} - -run_s2i_build_express() { - ct_s2i_build_as_df \ - "file://${test_dir}/express.js" "${IMAGE_NAME}" "${IMAGE_NAME}-express" \ - ${s2i_args} \ - $(ct_build_s2i_npm_variables) -e NODE_ENV=development -} - -prepare_dummy_git_repo() { - git init - for key in "${!gitconfig[@]}"; do - git config --local "$key" "${gitconfig[$key]}" - done - git add --all - git commit -m "Sample commit" -} - -prepare_express_repo() { - git clone \ - --config advice.detachedHead="false" \ - --branch "${EXPRESS_REVISION}" --depth 1 \ - 'https://github.com/expressjs/express.git' "$1" - pushd "$1" >/dev/null || return - for key in "${!gitconfig[@]}"; do - git config --local "$key" "${gitconfig[$key]}" - done - popd "$1" >/dev/null || return -} - -prepare() { - if ! image_exists ${IMAGE_NAME}; then - echo "ERROR: The image ${IMAGE_NAME} must exist before this script is executed." - exit 1 - fi - - case "$1" in - # TODO: STI build require the application is a valid 'GIT' repository, we - # should remove this restriction in the future when a file:// is used. - app|hw) - pushd "${test_dir}/test-${1}" >/dev/null - prepare_dummy_git_repo - popd >/dev/null - ;; - express) - prepare_express_repo "${test_dir}/express.js" - ;; - *) - echo "Please specify a valid test application" - exit 1 - ;; - esac -} - -run_test_application() { - if [[ $1 == app ]]; then - docker run --user=100001 $(ct_mount_ca_file) --rm --cidfile=${cid_file} $2 ${IMAGE_NAME}-testapp - elif [[ $1 == hw ]]; then - docker run --user=100001 $(ct_mount_ca_file) --rm --cidfile=${cid_file} $2 ${IMAGE_NAME}-testhw - else - echo "No such test application" - exit 1 - fi -} - -run_express_test_suite() { - docker run --user=100001 $(ct_mount_ca_file) --rm --cidfile=${cid_file} ${IMAGE_NAME}-express npm test -} - -kill_test_application() { - docker kill $(cat $cid_file) - rm $cid_file -} - -cleanup() { - if [ -f $cid_file ]; then - if container_exists; then - docker stop $(cat $cid_file) - fi - fi - - for image in "${IMAGE_NAME}"-{test{app,hw},express}; do - image_exists "$image" || continue - docker rmi -f "$image" - done - - rm -rf ${test_dir}/test-app/.git - rm -rf ${test_dir}/test-hw/.git - rm -rf "${test_dir}/express.js" -} - -check_result() { - local result="$1" - if [[ "$result" != "0" ]]; then - echo "S2I image '${IMAGE_NAME}' test FAILED (exit code: ${result})" - cleanup - exit $result - fi -} - -wait_for_cid() { - local max_attempts=20 - local sleep_time=1 - local attempt=1 - local result=1 - while [ $attempt -le $max_attempts ]; do - [ -f $cid_file ] && [ -s $cid_file ] && break - echo "Waiting for container start..." - attempt=$(( $attempt + 1 )) - sleep $sleep_time - done -} - -test_s2i_usage() { - echo "Testing 's2i usage'..." - ct_s2i_usage ${IMAGE_NAME} ${s2i_args} &>/dev/null -} - -test_docker_run_usage() { - echo "Testing 'docker run' usage..." - docker run --rm ${IMAGE_NAME} &>/dev/null -} - -test_connection() { - echo "Testing HTTP connection..." - local max_attempts=10 - local sleep_time=1 - local attempt=1 - local result=1 - while [ $attempt -le $max_attempts ]; do - echo "Sending GET request to http://$(container_ip):${test_port}/" - 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_scl_usage() { - local run_cmd="$1" - local expected="$2" - - echo "Testing the image SCL enable ..." - out=$(docker run --rm ${IMAGE_NAME} /bin/bash -c "${run_cmd}") - 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 -} - -validate_default_value() { - local label=$1 - - IFS=':' read -a label_vals <<< $(docker inspect -f "{{index .Config.Labels \"$label\"}}" ${IMAGE_NAME}) - label_var=${label_vals[0]} - default_label_val=${label_vals[1]} - - actual_label_val=$(docker run --rm $IMAGE_NAME /bin/bash -c "echo $"$label_var) - - if [ "$actual_label_val" != "$default_label_val" ]; then - echo "ERROR default value for $label with environment variable $label_var; Expected $default_label_val, got $actual_label_val" - return 1 - fi -} - -# Gets the NODE_ENV environment variable from the container. -get_node_env_from_container() { - local dev_mode="$1" - local node_env="$2" - - IFS=':' read -a label_val <<< $(docker inspect -f '{{index .Config.Labels "com.redhat.dev-mode"}}' $IMAGE_NAME) - dev_mode_label_var="${label_val[0]}" - - echo $(docker run --rm --env $dev_mode_label_var=$dev_mode --env NODE_ENV=$node_env $IMAGE_NAME /bin/bash -c 'echo "$NODE_ENV"') -} - -# Ensures that a docker container run with '--env NODE_ENV=$current_val' produces a NODE_ENV value of $expected when -# DEV_MODE=dev_mode. -validate_node_env() { - local current_val="$1" - local dev_mode_val="$2" - local expected="$3" - - actual=$(get_node_env_from_container "$dev_mode_val" "$current_val") - if [ "$actual" != "$expected" ]; then - echo "ERROR default value for NODE_ENV when development mode is $dev_mode_val; should be $expected but is $actual" - return 1 - fi -} - -test_dev_mode() { - local app=$1 - local dev_mode=$2 - local node_env=$3 - - echo "Testing $app DEV_MODE=$dev_mode NODE_ENV=$node_env" - - run_test_application $app "-e DEV_MODE=$dev_mode" & - wait_for_cid - - test_connection - check_result $? - - logs=$(container_logs) - echo ${logs} | grep -q DEV_MODE=$dev_mode - check_result $? - echo ${logs} | grep -q DEBUG_PORT=5858 - check_result $? - echo ${logs} | grep -q NODE_ENV=$node_env - check_result $? - - kill_test_application -} - -test_incremental_build() { - npm_variables=$(ct_build_s2i_npm_variables) - build_log1=$(ct_s2i_build_as_df file://${test_dir}/test-incremental ${IMAGE_NAME} ${IMAGE_NAME}-testapp ${s2i_args} ${npm_variables}) - check_result $? - build_log2=$(ct_s2i_build_as_df file://${test_dir}/test-incremental ${IMAGE_NAME} ${IMAGE_NAME}-testapp ${s2i_args} ${npm_variables} --incremental) - check_result $? - if [ "$VERSION" == "6" ]; then - # Different npm output for version 6 - if echo "$build_log2" | grep -e "\-\- yarn@[0-9\.]*"; then - echo "ERROR Incremental build failed: yarn package is getting installed in incremental build" - check_result 1 - fi - else - first=$(echo "$build_log1" | grep -o -e "added [0-9]* packages" | awk '{ print $2 }') - second=$(echo "$build_log2" | grep -o -e "added [0-9]* packages" | awk '{ print $2 }') - if [ "$first" == "$second" ]; then - echo "ERROR Incremental build failed: both builds installed $first packages" - check_result 1 - fi - fi - -} - -# Build the application image twice to ensure the 'save-artifacts' and -# 'restore-artifacts' scripts are working properly -prepare app -echo "Testing the production image build" -run_s2i_build -check_result $? - -# 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 $? - -# Verify that the HTTP connection can be established to test application container -run_test_application app & - -# Wait for the container to write it's CID file -wait_for_cid - -test_scl_usage "node --version" "v$VERSION." -check_result $? - -test_connection -check_result $? - -# Test that the development dependencies (nodemon) have been removed (npm prune) -devdep=$(docker run --rm ${IMAGE_NAME}-testapp /bin/bash -c "! test -d ~/node_modules/nodemon") -check_result $? - -# Test that the npm cache has been cleared -devdep=$(docker run --rm ${IMAGE_NAME}-testapp /bin/bash -c "! test -d \$(npm config get cache)") -check_result $? - -# Test that the npm tmp has been cleared -devdep=$(docker run --rm ${IMAGE_NAME}-testapp /bin/bash -c "! ls \$(npm config get tmp)/npm-* 2>/dev/null") -check_result $? - -kill_test_application - -test_dev_mode app false production -test_dev_mode app true development - -echo "Testing the development image build: s2i build -e \"NODE_ENV=development\")" -run_s2i_build "-e NODE_ENV=development" -check_result $? - -# Verify that the HTTP connection can be established to test application container -run_test_application app & -wait_for_cid - -test_connection -check_result $? - -# Test that the development dependencies (nodemon) have NOT been removed -devdep=$(docker run --rm ${IMAGE_NAME}-testapp /bin/bash -c "test -d ~/node_modules/nodemon") -check_result $? - -# Test that the npm cache has NOT been cleared -devdep=$(docker run --rm ${IMAGE_NAME}-testapp /bin/bash -c "test -d \$(npm config get cache)") -check_result $? - -kill_test_application - -test_dev_mode app true development -test_dev_mode app false development - -echo "Testing the development image build: s2i build -e \"DEV_MODE=true\")" -run_s2i_build "-e DEV_MODE=true" -check_result $? - -# Verify that the HTTP connection can be established to test application container -run_test_application app & -wait_for_cid - -test_connection -check_result $? - -# Test that the development dependencies (nodemon) have NOT been removed -devdep=$(docker run --rm ${IMAGE_NAME}-testapp /bin/bash -c "test -d ~/node_modules/nodemon") -check_result $? - -# Test that the npm cache has NOT been cleared -devdep=$(docker run --rm ${IMAGE_NAME}-testapp /bin/bash -c "test -d \$(npm config get cache)") -check_result $? - -kill_test_application - -test_dev_mode app true development -test_dev_mode app false production - -echo "Testing proxy safe logging..." -prepare hw -run_s2i_build_proxy http://user.password@0.0.0.0:8000 https://user.password@0.0.0.0:8000 > /tmp/build-log 2>&1 -if [[ $(grep redacted /tmp/build-log | wc -l) -eq 4 ]]; then - grep redacted /tmp/build-log - check_result 0 -else - echo "Some proxy log-in credentials were left in log file" - grep Setting /tmp/build-log - check_result 1 -fi - -run_test_application hw & -wait_for_cid -kill_test_application - -echo "Testing incremental build" -test_incremental_build - -echo "Testing npm availability" -ct_npm_works -check_result $? - -echo "Running express.js test suite" -prepare express -run_s2i_build_express; check_result $? -run_express_test_suite; check_result $? - -echo "Success!" -cleanup diff --git a/test/run-openshift b/test/run-openshift deleted file mode 100755 index 143f7dc..0000000 --- a/test/run-openshift +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash -# -# Test the NodeJS 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" - -# change the branch to a different value if a new change in the example -# app needs to be tested -BRANCH_TO_TEST=master - -set -eo nounset - -test -n "${IMAGE_NAME-}" || false 'make sure $IMAGE_NAME is defined' -test -n "${VERSION-}" || false 'make sure $VERSION is defined' - -ct_os_cluster_up -# TODO: We can make the tests work against examples inside the same PR -ct_os_test_s2i_app "${IMAGE_NAME}" "https://github.com/sclorg/s2i-nodejs-container.git" test/test-app "This is a node.js echo service" -ct_os_test_s2i_app "${IMAGE_NAME}" "https://github.com/sclorg/nodejs-ex.git" . "Welcome to your Node.js application on OpenShift" - -for template in nodejs.json nodejs-mongodb.json nodejs-mongodb-persistent.json ; do - - ct_os_test_template_app ${IMAGE_NAME} \ - https://raw.githubusercontent.com/sclorg/nodejs-ex/${BRANCH_TO_TEST}/openshift/templates/${template} \ - nodejs \ - "Welcome to your Node.js application on OpenShift" \ - 8080 http 200 "-p SOURCE_REPOSITORY_REF=${BRANCH_TO_TEST} -p SOURCE_REPOSITORY_URL=https://github.com/sclorg/nodejs-ex.git -p NODEJS_VERSION=${VERSION} -p NAME=nodejs-testing" -done diff --git a/test/test-app/README.md b/test/test-app/README.md deleted file mode 100644 index edd29eb..0000000 --- a/test/test-app/README.md +++ /dev/null @@ -1,4 +0,0 @@ -node-echo -========= - -node.js echo server, returns request data to response diff --git a/test/test-app/iisnode.yml b/test/test-app/iisnode.yml deleted file mode 100644 index 52b201b..0000000 --- a/test/test-app/iisnode.yml +++ /dev/null @@ -1,27 +0,0 @@ -# For documentation see https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/iisnode.yml - -# loggingEnabled: false -# debuggingEnabled: false -# devErrorsEnabled: false -node_env: production -# nodeProcessCountPerApplication: 1 -# maxConcurrentRequestsPerProcess: 1024 -# maxNamedPipeConnectionRetry: 24 -# namedPipeConnectionRetryDelay: 250 -# maxNamedPipeConnectionPoolSize: 512 -# maxNamedPipePooledConnectionAge: 30000 -# asyncCompletionThreadCount: 0 -# initialRequestBufferSize: 4096 -# maxRequestBufferSize: 65536 -watchedFiles: iisnode.yml;node_modules\*;*.js -# uncFileChangesPollingInterval: 5000 -# gracefulShutdownTimeout: 60000 -# logDirectoryNameSuffix: logs -# debuggerPortRange: 5058-6058 -# debuggerPathSegment: debug -# maxLogFileSizeInKB: 128 -# appendToExistingLog: false -# logFileFlushInterval: 5000 -# flushResponse: false -# enableXFF: false -# promoteServerVars: \ No newline at end of file diff --git a/test/test-app/package.json b/test/test-app/package.json deleted file mode 100644 index 7ec3c6b..0000000 --- a/test/test-app/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "node-echo", - "version": "0.0.1", - "description": "node-echo", - "main": "server.js", - "dependencies": { - }, - "devDependencies": { - "nodemon": "*" - }, - "engine": { - "node": "*", - "npm": "*" - }, - "scripts": { - "dev": "nodemon --ignore node_modules/ server.js", - "start": "node server.js" - }, - "repository": { - "type": "git", - "url": "http://github.com/bettiolo/node-echo.git" - }, - "keywords": [ - "Echo" - ], - "author": "Marco Bettiolo ", - "license": "", - "bugs": { - "url": "http://github.com/bettiolo/node-echo/issues" - }, - "homepage": "http://apilb.com" -} diff --git a/test/test-app/server.js b/test/test-app/server.js deleted file mode 100644 index f7c25b1..0000000 --- a/test/test-app/server.js +++ /dev/null @@ -1,50 +0,0 @@ -var util = require('util'); -var http = require('http'); -var url = require('url'); -var qs = require('querystring'); -var os = require('os') -var port = process.env.PORT || process.env.port || process.env.OPENSHIFT_NODEJS_PORT || 8080; -var ip = process.env.OPENSHIFT_NODEJS_IP || '0.0.0.0'; -var nodeEnv = process.env.NODE_ENV || 'unknown'; -var server = http.createServer(function (req, res) { - var url_parts = url.parse(req.url, true); - - var body = ''; - req.on('data', function (data) { - body += data; - }); - req.on('end', function () { - var formattedBody = qs.parse(body); - - res.writeHead(200, {'Content-Type': 'text/plain'}); - - res.write('This is a node.js echo service\n'); - res.write('Host: ' + req.headers.host + '\n'); - res.write('\n'); - res.write('node.js Production Mode: ' + (nodeEnv == 'production' ? 'yes' : 'no') + '\n'); - res.write('\n'); - res.write('HTTP/' + req.httpVersion +'\n'); - res.write('Request headers:\n'); - res.write(util.inspect(req.headers, null) + '\n'); - res.write('Request query:\n'); - res.write(util.inspect(url_parts.query, null) + '\n'); - res.write('Request body:\n'); - res.write(util.inspect(formattedBody, null) + '\n'); - res.write('\n'); - res.write('Host: ' + os.hostname() + '\n'); - res.write('OS Type: ' + os.type() + '\n'); - res.write('OS Platform: ' + os.platform() + '\n'); - res.write('OS Arch: ' + os.arch() + '\n'); - res.write('OS Release: ' + os.release() + '\n'); - res.write('OS Uptime: ' + os.uptime() + '\n'); - res.write('OS Free memory: ' + os.freemem() / 1024 / 1024 + 'mb\n'); - res.write('OS Total memory: ' + os.totalmem() / 1024 / 1024 + 'mb\n'); - res.write('OS CPU count: ' + os.cpus().length + '\n'); - res.write('OS CPU model: ' + os.cpus()[0].model + '\n'); - res.write('OS CPU speed: ' + os.cpus()[0].speed + 'mhz\n'); - res.end('\n'); - - }); -}); -server.listen(port); -console.log('Server running on ' + ip + ':' + port); diff --git a/test/test-app/web.config b/test/test-app/web.config deleted file mode 100644 index a6b44a3..0000000 --- a/test/test-app/web.config +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/test/test-hw/hw.js b/test/test-hw/hw.js deleted file mode 100644 index 1b7e0de..0000000 --- a/test/test-hw/hw.js +++ /dev/null @@ -1,11 +0,0 @@ -var http = require('http'); -var ip = process.env.OPENSHIFT_NODEJS_IP || '0.0.0.0'; -var port = process.env.PORT || process.env.port || process.env.OPENSHIFT_NODEJS_PORT || 8080; - -var server = http.createServer(function(req, res) { - res.writeHead(200); - res.end('Hello World!'); -}); -server.listen(port); - -console.log("Server running on " + ip + ":" + port); diff --git a/test/test-hw/package.json b/test/test-hw/package.json deleted file mode 100644 index 17b2475..0000000 --- a/test/test-hw/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "hello-world", - "version": "0.0.1", - "main": "hw.js", - "engine": { - "node": "*", - "npm": "*" - }, - "scripts": { - "start": "node hw.js", - "dev": "node hw.js" - }, - "license": "" -} diff --git a/test/test-incremental/README.md b/test/test-incremental/README.md deleted file mode 100644 index edd29eb..0000000 --- a/test/test-incremental/README.md +++ /dev/null @@ -1,4 +0,0 @@ -node-echo -========= - -node.js echo server, returns request data to response diff --git a/test/test-incremental/iisnode.yml b/test/test-incremental/iisnode.yml deleted file mode 100644 index 52b201b..0000000 --- a/test/test-incremental/iisnode.yml +++ /dev/null @@ -1,27 +0,0 @@ -# For documentation see https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/iisnode.yml - -# loggingEnabled: false -# debuggingEnabled: false -# devErrorsEnabled: false -node_env: production -# nodeProcessCountPerApplication: 1 -# maxConcurrentRequestsPerProcess: 1024 -# maxNamedPipeConnectionRetry: 24 -# namedPipeConnectionRetryDelay: 250 -# maxNamedPipeConnectionPoolSize: 512 -# maxNamedPipePooledConnectionAge: 30000 -# asyncCompletionThreadCount: 0 -# initialRequestBufferSize: 4096 -# maxRequestBufferSize: 65536 -watchedFiles: iisnode.yml;node_modules\*;*.js -# uncFileChangesPollingInterval: 5000 -# gracefulShutdownTimeout: 60000 -# logDirectoryNameSuffix: logs -# debuggerPortRange: 5058-6058 -# debuggerPathSegment: debug -# maxLogFileSizeInKB: 128 -# appendToExistingLog: false -# logFileFlushInterval: 5000 -# flushResponse: false -# enableXFF: false -# promoteServerVars: \ No newline at end of file diff --git a/test/test-incremental/package.json b/test/test-incremental/package.json deleted file mode 100644 index 2384b8a..0000000 --- a/test/test-incremental/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "node-echo", - "version": "0.0.1", - "description": "node-echo", - "main": "server.js", - "dependencies": { - "yarn": "*" - }, - "devDependencies": { - "nodemon": "*" - }, - "engine": { - "node": "*", - "npm": "*" - }, - "scripts": { - "dev": "nodemon --ignore node_modules/ server.js", - "start": "node server.js" - }, - "repository": { - "type": "git", - "url": "http://github.com/bettiolo/node-echo.git" - }, - "keywords": [ - "Echo" - ], - "author": "Marco Bettiolo ", - "license": "", - "bugs": { - "url": "http://github.com/bettiolo/node-echo/issues" - }, - "homepage": "http://apilb.com" -} diff --git a/test/test-incremental/server.js b/test/test-incremental/server.js deleted file mode 100644 index f7c25b1..0000000 --- a/test/test-incremental/server.js +++ /dev/null @@ -1,50 +0,0 @@ -var util = require('util'); -var http = require('http'); -var url = require('url'); -var qs = require('querystring'); -var os = require('os') -var port = process.env.PORT || process.env.port || process.env.OPENSHIFT_NODEJS_PORT || 8080; -var ip = process.env.OPENSHIFT_NODEJS_IP || '0.0.0.0'; -var nodeEnv = process.env.NODE_ENV || 'unknown'; -var server = http.createServer(function (req, res) { - var url_parts = url.parse(req.url, true); - - var body = ''; - req.on('data', function (data) { - body += data; - }); - req.on('end', function () { - var formattedBody = qs.parse(body); - - res.writeHead(200, {'Content-Type': 'text/plain'}); - - res.write('This is a node.js echo service\n'); - res.write('Host: ' + req.headers.host + '\n'); - res.write('\n'); - res.write('node.js Production Mode: ' + (nodeEnv == 'production' ? 'yes' : 'no') + '\n'); - res.write('\n'); - res.write('HTTP/' + req.httpVersion +'\n'); - res.write('Request headers:\n'); - res.write(util.inspect(req.headers, null) + '\n'); - res.write('Request query:\n'); - res.write(util.inspect(url_parts.query, null) + '\n'); - res.write('Request body:\n'); - res.write(util.inspect(formattedBody, null) + '\n'); - res.write('\n'); - res.write('Host: ' + os.hostname() + '\n'); - res.write('OS Type: ' + os.type() + '\n'); - res.write('OS Platform: ' + os.platform() + '\n'); - res.write('OS Arch: ' + os.arch() + '\n'); - res.write('OS Release: ' + os.release() + '\n'); - res.write('OS Uptime: ' + os.uptime() + '\n'); - res.write('OS Free memory: ' + os.freemem() / 1024 / 1024 + 'mb\n'); - res.write('OS Total memory: ' + os.totalmem() / 1024 / 1024 + 'mb\n'); - res.write('OS CPU count: ' + os.cpus().length + '\n'); - res.write('OS CPU model: ' + os.cpus()[0].model + '\n'); - res.write('OS CPU speed: ' + os.cpus()[0].speed + 'mhz\n'); - res.end('\n'); - - }); -}); -server.listen(port); -console.log('Server running on ' + ip + ':' + port); diff --git a/test/test-incremental/web.config b/test/test-incremental/web.config deleted file mode 100644 index a6b44a3..0000000 --- a/test/test-incremental/web.config +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/test/test-lib-openshift.sh b/test/test-lib-openshift.sh deleted file mode 120000 index f48003b..0000000 --- a/test/test-lib-openshift.sh +++ /dev/null @@ -1 +0,0 @@ -../common/test-lib-openshift.sh \ No newline at end of file diff --git a/test/test-lib.sh b/test/test-lib.sh deleted file mode 120000 index 6ddf876..0000000 --- a/test/test-lib.sh +++ /dev/null @@ -1 +0,0 @@ -../common/test-lib.sh \ No newline at end of file