Compare commits
2 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
50d809fe91 | ||
|
|
ec99273a20 |
62 changed files with 1 additions and 4654 deletions
0
.gitignore
vendored
0
.gitignore
vendored
|
|
@ -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
|
||||
49
.s2i/bin/run
49
.s2i/bin/run
|
|
@ -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
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
#!/bin/bash -e
|
||||
cat <<EOF
|
||||
This is the nodejs S2I image:
|
||||
To use it, install S2I: https://github.com/openshift/source-to-image
|
||||
|
||||
Sample invocation:
|
||||
|
||||
s2i build <source code path/URL> nodejs:6 <application image>
|
||||
|
||||
You can then run the resulting image via:
|
||||
docker run <application image>
|
||||
EOF
|
||||
78
Dockerfile
78
Dockerfile
|
|
@ -1,78 +0,0 @@
|
|||
FROM registry.fedoraproject.org/f32/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=12 \
|
||||
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 <sclorg@redhat.com>" \
|
||||
help="For more information visit https://github.com/sclorg/s2i-nodejs-container" \
|
||||
usage="s2i build <SOURCE-REPOSITORY> centos/$NAME-$NODEJS_VERSION-centos7:latest <APP-NAME>"
|
||||
|
||||
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
|
||||
163
README.md
163
README.md
|
|
@ -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 <CONTAINER_ID> /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.
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
language: shell
|
||||
os: linux
|
||||
script:
|
||||
- make shellcheck
|
||||
202
common/LICENSE
202
common/LICENSE
|
|
@ -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.
|
||||
|
|
@ -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
|
||||
100
common/README.md
100
common/README.md
|
|
@ -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
|
||||
183
common/build.sh
183
common/build.sh
|
|
@ -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
|
||||
|
|
@ -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
|
||||
146
common/common.mk
146
common/common.mk
|
|
@ -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
|
||||
|
|
@ -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:
|
||||
# <rules_type>="
|
||||
# src=<path to source>
|
||||
# dest=<path to destination>
|
||||
# mode=<destination file mode (optional)>;
|
||||
# ...;
|
||||
# "
|
||||
#
|
||||
# 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 <<EOF
|
||||
COPY_TARGETS = $COPY_TARGETS
|
||||
|
||||
DISTGEN_TARGETS = $DISTGEN_TARGETS
|
||||
|
||||
DISTGEN_MULTI_TARGETS = $DISTGEN_MULTI_TARGETS
|
||||
|
||||
SYMLINK_TARGETS = $SYMLINK_TARGETS
|
||||
EOF
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
VERBOSE_OUTPUT=0
|
||||
|
||||
usage() {
|
||||
echo "Usage: $(basename "$0") [ -v|--verbose ] <dir|file> [ <dir|file> ... ]"
|
||||
}
|
||||
|
||||
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:
|
||||
|
|
@ -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()
|
||||
)
|
||||
|
|
@ -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
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -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=<container>_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:
|
||||
# <output_dir>/<base_name>-cert-selfsigned.pem -- public PEM cert
|
||||
# <output_dir>/<base_name>-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 <<EOF >"$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:
|
||||
|
|
@ -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:
|
||||
|
|
@ -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
|
||||
2
common/tests/.gitignore
vendored
2
common/tests/.gitignore
vendored
|
|
@ -1,2 +0,0 @@
|
|||
.image-id*
|
||||
help.1
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
# Variables are documented in common/build.sh.
|
||||
BASE_IMAGE_NAME = test-container
|
||||
VERSIONS = v0
|
||||
include common/common.mk
|
||||
|
|
@ -1 +0,0 @@
|
|||
../../..
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
FROM centos/s2i-core-centos7
|
||||
LABEL name=test-image
|
||||
|
|
@ -1 +0,0 @@
|
|||
This is just no-op-build container.
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#! /bin/sh -x
|
||||
|
||||
false this must fail the whole testsuite
|
||||
|
|
@ -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
|
||||
1
common/tests/squash/.gitignore
vendored
1
common/tests/squash/.gitignore
vendored
|
|
@ -1 +0,0 @@
|
|||
Dockerfile
|
||||
|
|
@ -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 <<EOF
|
||||
FROM $origin
|
||||
ENV test=test
|
||||
CMD /bin/echo test
|
||||
EOF
|
||||
out=`docker build . | awk '/Successfully built/{print $NF}'`
|
||||
echo "$out"
|
||||
squashed=$("${PYTHON-python3}" "$squash" "$out" "$origin")
|
||||
output=$(docker run --rm $squashed)
|
||||
test "$output" = "test"
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
. test-lib.sh
|
||||
|
||||
# This should succeed
|
||||
if ! ct_check_image_availability docker.io/centos/postgresql-10-centos7; then
|
||||
echo "image_availability test failed"
|
||||
fi
|
||||
|
||||
# This should fail
|
||||
if ct_check_image_availability docker.io/centos/postgresql-98-centos7; then
|
||||
echo "image_availability test failed"
|
||||
fi
|
||||
|
||||
echo "image_availability test completed successfully."
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
#! /bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
. test-lib.sh
|
||||
|
||||
path='a b c:d x:y'
|
||||
exp_output="==a b c==
|
||||
==.==
|
||||
==d x==
|
||||
==.==
|
||||
==y==
|
||||
==.=="
|
||||
|
||||
wrap() { for arg; do echo "==$arg=="; done; }
|
||||
|
||||
test "$(ct_path_foreach "$path" wrap .)" == "$exp_output"
|
||||
|
||||
ct_path_append path '/a'
|
||||
exp_output="==/a==
|
||||
==.==
|
||||
$exp_output"
|
||||
|
||||
test "$(ct_path_foreach "$path" wrap .)" == "$exp_output"
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
. test-lib.sh
|
||||
|
||||
combinations="rhel7:registry.redhat.io/rhscl/postgresql-10-rhel7
|
||||
centos7:docker.io/centos/postgresql-10-centos7
|
||||
rhel8:registry.redhat.io/rhel8/postgresql-10
|
||||
"
|
||||
|
||||
for c in $combinations; do
|
||||
public_name=$(ct_get_public_image_name "${c%%:*}" postgresql 10)
|
||||
[ "$public_name" == "${c#*:}" ]
|
||||
done
|
||||
|
||||
echo "public_image_name test completed successfully."
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
#! /bin/bash
|
||||
|
||||
set -e
|
||||
. test-lib.sh
|
||||
|
||||
x=$(ct_random_string)
|
||||
test ${#x} -eq 10
|
||||
|
||||
for i in 5 9 11 13; do
|
||||
x=$(ct_random_string $i)
|
||||
test ${#x} -eq $i
|
||||
done
|
||||
|
||||
# Even with ignored sigpipe we have to succeed promptly (#70).
|
||||
trap '' SIGPIPE
|
||||
x=$(ct_random_string 20)
|
||||
test ${#x} -eq 20
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
#! /bin/bash
|
||||
|
||||
set -ex
|
||||
|
||||
. test-lib.sh
|
||||
|
||||
NPM_REGISTRY=""
|
||||
output=$(ct_build_s2i_npm_variables)
|
||||
test x"$output" == "x"
|
||||
|
||||
ca_file="/etc/pki/ca-trust/source/anchors/RH-IT-Root-CA.crt"
|
||||
NPM_REGISTRY="https://foobar.registry.org"
|
||||
if [ -f "$ca_file" ]; then
|
||||
output=$(ct_build_s2i_npm_variables)
|
||||
test x"$output" == "x-e NPM_MIRROR=$NPM_REGISTRY -v $ca_file:$ca_file:Z"
|
||||
fi
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -ex
|
||||
shopt -s extglob
|
||||
|
||||
COMMIT=$(git rev-parse HEAD)
|
||||
|
||||
# import generated content from this git reference ..
|
||||
SOURCE_BRANCH=${1:-$COMMIT}
|
||||
|
||||
# into this git branch
|
||||
GENERATED_BRANCH=${2:-generated}
|
||||
|
||||
git clean -f -d
|
||||
|
||||
# switch to generated branch for working env; and switch back later
|
||||
git checkout "$GENERATED_BRANCH"
|
||||
git submodule update
|
||||
|
||||
# Clean everything in generated branch.
|
||||
rm -rf -- *
|
||||
|
||||
srcdir=srcdir
|
||||
|
||||
cleanup ()
|
||||
{
|
||||
exit_status=$?
|
||||
rm -rf "$srcdir"
|
||||
|
||||
# switch back to initial ranch
|
||||
git checkout "$SOURCE_BRANCH"
|
||||
git submodule update
|
||||
|
||||
return $exit_status
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
(
|
||||
# Copy the actual repo into $srcdir, and generate there
|
||||
mkdir "$srcdir"
|
||||
cd "$srcdir"
|
||||
git clone .. .
|
||||
git checkout "$SOURCE_BRANCH"
|
||||
git submodule update --init
|
||||
make generate-all
|
||||
)
|
||||
|
||||
# copy the relevant (generated) content from $srcdir
|
||||
versions=$(sed -n 's/^VERSIONS[[:space:]]*=//p' "$srcdir"/Makefile)
|
||||
for i in $versions; do
|
||||
cp -r "$srcdir/$i" .
|
||||
done
|
||||
|
||||
# source directory is not needed anymore
|
||||
rm -rf "$srcdir"
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
git add $versions
|
||||
|
||||
# Add deleted files to the index as well
|
||||
(
|
||||
IFS=$'\n'
|
||||
for i in $(git ls-files --deleted) ;do
|
||||
git add --all "$i"
|
||||
done
|
||||
)
|
||||
|
||||
if ! git diff --cached --exit-code --quiet ; then
|
||||
git commit -m "auto-sync: master commit $COMMIT"
|
||||
else
|
||||
echo "Nothing changed"
|
||||
fi
|
||||
1
dead.package
Normal file
1
dead.package
Normal file
|
|
@ -0,0 +1 @@
|
|||
container sources not used for building fedora containers anymore
|
||||
1
help.md
1
help.md
|
|
@ -1 +0,0 @@
|
|||
README.md
|
||||
247
root/help.1
247
root/help.1
|
|
@ -1,247 +0,0 @@
|
|||
.TH NodeJS 12 container image
|
||||
.PP
|
||||
This container image includes Node.JS 12 as a S2I
|
||||
\[la]https://github.com/openshift/source-to-image\[ra] base image for your Node.JS 12 applications.
|
||||
Users can choose between RHEL, CentOS and Fedora based images.
|
||||
The RHEL images are available in the Red Hat Container Catalog
|
||||
\[la]https://access.redhat.com/containers/\[ra],
|
||||
the CentOS images are available on Podman Hub
|
||||
\[la]https://hub.docker.com/r/centos/\[ra],
|
||||
and the Fedora images are available in Fedora Registry
|
||||
\[la]https://registry.fedoraproject.org/\[ra]\&.
|
||||
The resulting image can be run using podman
|
||||
\[la]https://github.com/containers/libpod\[ra]\&.
|
||||
|
||||
.PP
|
||||
Note: while the examples in this README are calling \fB\fCpodman\fR, you can replace any such calls by \fB\fCdocker\fR with the same arguments
|
||||
|
||||
.SH Description
|
||||
.PP
|
||||
Node.js 12 available as container is a base platform for
|
||||
building and running various Node.js 12 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.
|
||||
|
||||
.SH Usage
|
||||
.PP
|
||||
For this, we will assume that you are using the \fB\fCubi8/nodejs\-12 image\fR, available via \fB\fCnodejs:12\fR imagestream tag in Openshift.
|
||||
Building a simple nodejs\-sample\-app
|
||||
\[la]https://github.com/sclorg/s2i-nodejs-container/tree/master/12/test/test-app\[ra] application
|
||||
in Openshift can be achieved with the following step:
|
||||
|
||||
.PP
|
||||
.RS
|
||||
|
||||
.nf
|
||||
```
|
||||
oc new\-app nodejs:12\~https://github.com/sclorg/s2i\-nodejs\-container.git \-\-context\-dir=12/test/test\-app/
|
||||
```
|
||||
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.PP
|
||||
The same application can also be built using the standalone S2I
|
||||
\[la]https://github.com/openshift/source-to-image\[ra] application on systems that have it available:
|
||||
|
||||
.PP
|
||||
.RS
|
||||
|
||||
.nf
|
||||
```
|
||||
$ s2i build https://github.com/sclorg/s2i\-nodejs\-container.git \-\-context\-dir=12/test/test\-app/ ubi8/nodejs\-12 nodejs\-sample\-app
|
||||
```
|
||||
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.PP
|
||||
\fBAccessing the application:\fP
|
||||
|
||||
.PP
|
||||
.RS
|
||||
|
||||
.nf
|
||||
$ curl 127.0.0.1:8080
|
||||
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.SH Environment variables
|
||||
.PP
|
||||
Application developers can use the following environment variables to configure the runtime behavior of this image:
|
||||
|
||||
.PP
|
||||
\fB\fB\fCNODE\_ENV\fR\fP
|
||||
.br
|
||||
NodeJS runtime mode (default: "production")
|
||||
|
||||
.PP
|
||||
\fB\fB\fCDEV\_MODE\fR\fP
|
||||
.br
|
||||
When set to "true", \fB\fCnodemon\fR will be used to automatically reload the server while you work (default: "false"). Setting \fB\fCDEV\_MODE\fR to "true" will change the \fB\fCNODE\_ENV\fR default to "development" (if not explicitly set).
|
||||
|
||||
.PP
|
||||
\fB\fB\fCNPM\_RUN\fR\fP
|
||||
.br
|
||||
Select an alternate / custom runtime mode, defined in your \fB\fCpackage.json\fR file's \fB\fCscripts\fR
|
||||
\[la]https://docs.npmjs.com/misc/scripts\[ra] section (default: npm run "start"). These user\-defined run\-scripts are unavailable while \fB\fCDEV\_MODE\fR is in use.
|
||||
|
||||
.PP
|
||||
\fB\fB\fCHTTP\_PROXY\fR\fP
|
||||
.br
|
||||
Use an npm proxy during assembly
|
||||
|
||||
.PP
|
||||
\fB\fB\fCHTTPS\_PROXY\fR\fP
|
||||
.br
|
||||
Use an npm proxy during assembly
|
||||
|
||||
.PP
|
||||
\fB\fB\fCNPM\_MIRROR\fR\fP
|
||||
.br
|
||||
Use a custom NPM registry mirror to download packages during the build process
|
||||
|
||||
.PP
|
||||
One way to define a set of environment variables is to include them as key value pairs in your repo's \fB\fC\&.s2i/environment\fR file.
|
||||
|
||||
.PP
|
||||
Example: DATABASE\_USER=sampleUser
|
||||
|
||||
.SS NOTE: Define your own "\fB\fCDEV\_MODE\fR":
|
||||
.PP
|
||||
The following \fB\fCpackage.json\fR example includes a \fB\fCscripts.dev\fR entry. You can define your own custom \fB\fCNPM\_RUN\fR
|
||||
\[la]https://docs.npmjs.com/cli/run-script\[ra] scripts in your application's \fB\fCpackage.json\fR file.
|
||||
|
||||
.SS Note: Setting logging output verbosity
|
||||
.PP
|
||||
To alter the level of logs output during an \fB\fCnpm install\fR the npm\_config\_loglevel environment variable can be set. See npm\-config
|
||||
\[la]https://docs.npmjs.com/misc/config\[ra]\&.
|
||||
|
||||
.SH Development Mode
|
||||
.PP
|
||||
This image supports development mode. This mode can be switched on and off with the environment variable \fB\fCDEV\_MODE\fR\&. \fB\fCDEV\_MODE\fR can either be set to \fB\fCtrue\fR or \fB\fCfalse\fR\&.
|
||||
Development mode supports two features:
|
||||
* Hot Deploy
|
||||
* Debugging
|
||||
|
||||
.PP
|
||||
The debug port can be specified with the environment variable \fB\fCDEBUG\_PORT\fR\&. \fB\fCDEBUG\_PORT\fR is only valid if \fB\fCDEV\_MODE=true\fR\&.
|
||||
|
||||
.PP
|
||||
A simple example command for running the container in development mode is:
|
||||
|
||||
.PP
|
||||
.RS
|
||||
|
||||
.nf
|
||||
podman run \-\-env DEV\_MODE=true my\-image\-id
|
||||
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.PP
|
||||
To run the container in development mode with a debug port of 5454, run:
|
||||
|
||||
.PP
|
||||
.RS
|
||||
|
||||
.nf
|
||||
$ podman run \-\-env DEV\_MODE=true DEBUG\_PORT=5454 my\-image\-id
|
||||
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.PP
|
||||
To run the container in production mode, run:
|
||||
|
||||
.PP
|
||||
.RS
|
||||
|
||||
.nf
|
||||
$ podman run \-\-env DEV\_MODE=false my\-image\-id
|
||||
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.PP
|
||||
By default, \fB\fCDEV\_MODE\fR is set to \fB\fCfalse\fR, and \fB\fCDEBUG\_PORT\fR is set to \fB\fC5858\fR, however the \fB\fCDEBUG\_PORT\fR is only relevant if \fB\fCDEV\_MODE=true\fR\&.
|
||||
|
||||
.SH Hot deploy
|
||||
.PP
|
||||
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.
|
||||
|
||||
.SS Using Podman's exec
|
||||
.PP
|
||||
To change your source code in a running container, use Podman's exec
|
||||
\[la]https://github.com/containers/libpod\[ra] command:
|
||||
|
||||
.PP
|
||||
.RS
|
||||
|
||||
.nf
|
||||
$ podman exec \-it <CONTAINER\_ID> /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.
|
||||
|
|
@ -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
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
async
|
||||
mime
|
||||
mkdirp
|
||||
qs
|
||||
minimatch
|
||||
|
|
@ -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}
|
||||
116
s2i/bin/assemble
116
s2i/bin/assemble
|
|
@ -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 ./
|
||||
60
s2i/bin/run
60
s2i/bin/run
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
DISTRO=`cat /etc/*-release | grep ^ID= | grep -Po '".*?"' | tr -d '"'`
|
||||
|
||||
cat <<EOF
|
||||
This is a S2I nodejs-8 ${DISTRO} base image:
|
||||
To use it, install S2I: https://github.com/openshift/source-to-image
|
||||
|
||||
Sample invocation:
|
||||
|
||||
s2i build https://github.com/sclorg/s2i-nodejs-container.git --context-dir=8/test/test-app/ ${NAMESPACE}/nodejs-8-${DISTRO}7 nodejs-sample-app
|
||||
|
||||
You can then run the resulting image via:
|
||||
podman run -p 8080:8080 nodejs-sample-app
|
||||
EOF
|
||||
444
test/run
444
test/run
|
|
@ -1,444 +0,0 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# The 'run' performs a simple test that verifies that STI image.
|
||||
# The main focus here is to exercise the STI scripts.
|
||||
#
|
||||
# IMAGE_NAME specifies a name of the candidate image used for testing.
|
||||
# The image has to be available before this script is executed.
|
||||
#
|
||||
# EXPRESS_REVISION specifies which express.js branch or tag should be tested;
|
||||
# by default it uses the latest released version as reported by
|
||||
# `npm show express version`.
|
||||
|
||||
THISDIR=$(dirname ${BASH_SOURCE[0]})
|
||||
|
||||
source "${THISDIR}/test-lib.sh"
|
||||
|
||||
test -n $IMAGE_NAME \
|
||||
-a -n $VERSION
|
||||
readonly EXPRESS_REVISION="${EXPRESS_REVISION:-$(docker run --rm "${IMAGE_NAME}" -- npm show express version)}"
|
||||
|
||||
test_dir="$(readlink -f $(dirname ${BASH_SOURCE[0]}))"
|
||||
image_dir="$(readlink -f ${test_dir}/..)"
|
||||
cid_file=$(mktemp -u --suffix=.cid)
|
||||
|
||||
# Since we built the candidate image locally, we don't want S2I attempt to pull
|
||||
# it from Docker hub
|
||||
s2i_args="--pull-policy=never "
|
||||
|
||||
# TODO: This should be part of the image metadata
|
||||
test_port=8080
|
||||
|
||||
# Common git configuration
|
||||
readonly -A gitconfig=(
|
||||
[user.name]="builder"
|
||||
[user.email]="build@localhost"
|
||||
[commit.gpgsign]="false"
|
||||
)
|
||||
|
||||
info() {
|
||||
echo -e "\n\e[1m[INFO] $@...\e[0m\n"
|
||||
}
|
||||
|
||||
if [ "$DEBUG" != "" ]; then
|
||||
set -x
|
||||
fi
|
||||
|
||||
image_exists() {
|
||||
docker inspect $1 &>/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
|
||||
|
|
@ -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
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
node-echo
|
||||
=========
|
||||
|
||||
node.js echo server, returns request data to response
|
||||
|
|
@ -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:
|
||||
|
|
@ -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 <marco@bettiolo.it>",
|
||||
"license": "",
|
||||
"bugs": {
|
||||
"url": "http://github.com/bettiolo/node-echo/issues"
|
||||
},
|
||||
"homepage": "http://apilb.com"
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
<configuration>
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<add name="iisnode" path="server.js" verb="*" modules="iisnode" />
|
||||
</handlers>
|
||||
<iisnode loggingEnabled="false" />
|
||||
|
||||
<rewrite>
|
||||
<rules>
|
||||
<rule name="myapp">
|
||||
<match url="/*" />
|
||||
<action type="Rewrite" url="server.js" />
|
||||
</rule>
|
||||
</rules>
|
||||
</rewrite>
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
|
|
@ -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);
|
||||
|
|
@ -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": ""
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
node-echo
|
||||
=========
|
||||
|
||||
node.js echo server, returns request data to response
|
||||
|
|
@ -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:
|
||||
|
|
@ -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 <marco@bettiolo.it>",
|
||||
"license": "",
|
||||
"bugs": {
|
||||
"url": "http://github.com/bettiolo/node-echo/issues"
|
||||
},
|
||||
"homepage": "http://apilb.com"
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
<configuration>
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<add name="iisnode" path="server.js" verb="*" modules="iisnode" />
|
||||
</handlers>
|
||||
<iisnode loggingEnabled="false" />
|
||||
|
||||
<rewrite>
|
||||
<rules>
|
||||
<rule name="myapp">
|
||||
<match url="/*" />
|
||||
<action type="Rewrite" url="server.js" />
|
||||
</rule>
|
||||
</rules>
|
||||
</rewrite>
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
|
|
@ -1 +0,0 @@
|
|||
../common/test-lib-openshift.sh
|
||||
|
|
@ -1 +0,0 @@
|
|||
../common/test-lib.sh
|
||||
Loading…
Add table
Add a link
Reference in a new issue