From c4b68b0a77bb7a8a691a59c9c944a72bc9599c3f Mon Sep 17 00:00:00 2001 From: Jan Koscielniak Date: Thu, 20 Apr 2017 14:17:35 +0200 Subject: [PATCH 1/6] Initial commit --- Dockerfile | 71 +++++++++++++ README.md | 124 +++++++++++++++++++++ bin/cgroup-limits | 92 ++++++++++++++++ bin/fix-permissions | 12 +++ contrib/etc/httpd.conf | 18 ++++ contrib/etc/httpd.d/50-mpm.conf.template | 11 ++ contrib/etc/httpdconf.sed | 7 ++ openshift-template.yml | 130 +++++++++++++++++++++++ root/help.1 | 102 ++++++++++++++++++ root/help.md | 63 +++++++++++ s2i/bin/assemble | 76 +++++++++++++ s2i/bin/run | 46 ++++++++ s2i/bin/usage | 11 ++ 13 files changed, 763 insertions(+) create mode 100644 Dockerfile create mode 100644 README.md create mode 100755 bin/cgroup-limits create mode 100755 bin/fix-permissions create mode 100644 contrib/etc/httpd.conf create mode 100644 contrib/etc/httpd.d/50-mpm.conf.template create mode 100644 contrib/etc/httpdconf.sed create mode 100644 openshift-template.yml create mode 100644 root/help.1 create mode 100644 root/help.md create mode 100755 s2i/bin/assemble create mode 100755 s2i/bin/run create mode 100755 s2i/bin/usage diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0a3f058 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,71 @@ +FROM registry.fedoraproject.org/fedora:25 + +# Port on which will apache run +EXPOSE 8080 + +# Image metadata +ENV NAME=perl \ + PERL_VERSION=5.24 \ + VERSION=0 \ + RELEASE=1 \ + ARCH=x86_64 + +# Set labels used in OpenShift to describe the builder images +LABEL com.redhat.component="$NAME" \ + name="$FGC/$NAME" \ + summary="Perl 5 is a highly capable, feature-rich programming language." \ + description="Perl 5 is a highly capable, feature-rich programming language with over 29 years of development. Perl 5 runs on over 100 platforms." \ + version="$VERSION" \ + release="$RELEASE.$DISTTAG" \ + architecture="$ARCH" \ + usage="s2i build file:///your/app modularitycontainers/perl your-app" \ + io.k8s.description="Platform for building and running Perl 5.24 applications" \ + io.k8s.display-name="Apache 2.4 with mod_perl/5.24" \ + io.openshift.expose-services="8080:http" \ + io.openshift.tags="builder,perl,perl524" \ + io.openshift.s2i.scripts-url=image:///usr/local/s2i + +# Perl and build tools install + user addition + +RUN BUILD_TOOlS="bsdtar \ + findutils \ + gcc \ + make \ + gettext \ + tar \ + wget \ + python " && \ + dnf install -y --setopt=tsflags=nodocs perl perl-devel mod_perl cpan cpanminus httpd \ + $BUILD_TOOlS && \ + dnf clean all && \ + mkdir -p /opt/app-root/src/ && \ + useradd -u 1001 -r -g 0 -d /opt/app-root/src -s /sbin/nologin \ + -c "Default Application User" default && \ + chown -R 1001:0 /opt/app-root + +# Copy s2i files +COPY ./s2i/bin/ /usr/local/s2i + +# Copy apache configuration +COPY ./contrib/ /opt/app-root + +# Drop the root user +RUN mkdir -p /opt/app-root/etc/httpd.d && \ + sed -i -f /opt/app-root/etc/httpdconf.sed etc/httpd/conf/httpd.conf && \ + chmod -R og+rwx /var/run/httpd /opt/app-root/etc/httpd.d && \ + chown -R 1001:0 /opt/app-root && chmod -R ug+rwx /opt/app-root + +USER 1001 + +# Copy executable utilities. +COPY bin/ /usr/bin/ + +# Copy help file +COPY root/help.1 / + +# Directory with the sources is set as the working directory so all STI scripts +# can execute relative to this path. +WORKDIR /opt/app-root/src + +# Set the default command to print the usage +CMD /usr/local/s2i/usage diff --git a/README.md b/README.md new file mode 100644 index 0000000..06cfba0 --- /dev/null +++ b/README.md @@ -0,0 +1,124 @@ +# Perl S2I +This repository contains the sources for S2I builder image for perl 5.24 as well as some sample applications. This is a port to Fedora of software collections Perl located [here](https://github.com/sclorg/s2i-perl-container). Please note that this solution uses httpd 2.4 to display results. + +# Usage +## Docker +First you need to build the builder image. After you have the builder image, you can use it for a S2I build. You can build and run the sample app like this: +``` +$ docker build --tag=koscicz/perl . +$ s2i build https://github.com/container-images/perl.git --context-dir=test/sample-test-app/ koscicz/perl perl-sample-app +$ docker run -p 8080:8080 perl-sample-app +``` +This will build and run you application on 127.0.0.1:8080. You can also build the builder image by running `make`. This will also tag your image as koscicz/perl. + +## Openshift +You can use the `openshift-template.yml` in this repository to run your application in Openshift. You can either use web interface, in which case you'll just have to fill out a form, requiring a source repository for your app and name of this app. In case you want to use cli, you can do it like this, after you login: +``` +$ oc new-project perl-test +$ oc new-app https://raw.githubusercontent.com/container-images/perl/master/openshift-template.yml -p APP_NAME="perl-example" -p SOURCE_REPOSITORY="https://github.com/kosciCZ/perl-example" +``` +These commands will build the sample application on your Openshift platform. + +# Testing +This repository contains a `test` folder with some tests to ensure proper functionality. You can run test by using Makefile. You have two options: +* `make all` This will build, tag and test the image +* `make test` This will run the test on the image, that is defined in the Makefile. By default it is koscicz/perl +Or you can execute the test script directly, as described below in [Repository organization](#repository-organization) + +Repository organization +------------------------ +* **Dockerfile** + + Fedora based Dockerfile. + +* **`s2i/bin/`** + + This folder contains scripts that are run by [S2I](https://github.com/openshift/source-to-image): + + * **assemble** + + Used to install the sources into a location where the application + will be run and prepare the application for deployment (eg. installing + modules, etc.). + In order to install application dependencies, the application must contain a + `cpanfile` file, in which the user specifies the modules and their versions. + An example of a [cpanfile](https://github.com/container-images/perl/blob/master/test/sample-test-app/cpanfile) is available within our test application. + + All files with `.cgi` and `.pl` extension are handled by mod_perl. + If exactly one file with `.psgi` extension exists in the top-level + directory, the mod_perl will be autoconfigured to execute the PSGI + application for any request URI path with Plack's mod_perl adaptor. + + * **run** + + This script is responsible for running the application, using the + Apache web server. + + * **usage*** + + This script prints the usage of this image. + +* **`contrib/`** + + This folder contains a file with commonly used modules. + +* **`test/`** + + This folder contains some sample applications you can use to test you image. + + * **`sample-test-app/`** + + A simple Perl application used for testing purposes by the [S2I](https://github.com/openshift/source-to-image) test framework. + + * **run** + + This is a script that runs a test suite on the builder image, to ensure it has all the necessary functionality. + Run it by `./run IMAGE`, where `IMAGE` is your builder image. + +Environment variables +--------------------- + +To set environment variables, you can place them as a key value pair into a `.sti/environment` +file inside your source code repository. + +* **ENABLE_CPAN_TEST** + + Allow the installation of all specified cpan packages and the running of their tests. The default value is `false`. + +* **CPAN_MIRROR** + + This variable specifies a mirror URL which will used by cpanminus to install dependencies. + By default the URL is not specified. + +* **PERL_APACHE2_RELOAD** + + Set this to "true" to enable automatic reloading of modified Perl modules. + +* **HTTPD_START_SERVERS** + + The [StartServers](https://httpd.apache.org/docs/2.4/mod/mpm_common.html#startservers) + directive sets the number of child server processes created on startup. Default is 8. + +* **HTTPD_MAX_REQUEST_WORKERS** + + Number of simultaneous requests that will be handled by Apache. The default + is 256, but it will be automatically lowered if memory is limited. + +* **PSGI_FILE** + + Override PSGI application detection. + + If the PSGI_FILE variable is set to empty value, no PSGI application will + be detected and mod_perl not be reconfigured. + + If the PSGI_FILE variable is set and non-empty, it will define path to + the PSGI application file. No detection will be used. + + If the PSGI_FILE variable does not exist, autodetection will be used: + If exactly one ./*.psgi file exists, mod_perl will be configured to + execute that file. + +* **PSGI_URI_PATH** + + This variable overrides location URI path that is handled path the PSGI + application. Default value is "/". \ No newline at end of file diff --git a/bin/cgroup-limits b/bin/cgroup-limits new file mode 100755 index 0000000..3107fbf --- /dev/null +++ b/bin/cgroup-limits @@ -0,0 +1,92 @@ +#!/usr/bin/python + +""" +Script for parsing cgroup information + +This script will read some limits from the cgroup system and parse +them, printing out "VARIABLE=VALUE" on each line for every limit that is +successfully read. Output of this script can be directly fed into +bash's export command. Recommended usage from a bash script: + + set -o errexit + export_vars=$(cgroup-limits) ; export $export_vars + +Variables currently supported: + MAX_MEMORY_LIMIT_IN_BYTES + Maximum possible limit MEMORY_LIMIT_IN_BYTES can have. This is + currently constant value of 9223372036854775807. + MEMORY_LIMIT_IN_BYTES + Maximum amount of user memory in bytes. If this value is set + to the same value as MAX_MEMORY_LIMIT_IN_BYTES, it means that + there is no limit set. The value is taken from + /sys/fs/cgroup/memory/memory.limit_in_bytes + NUMBER_OF_CORES + Number of detected CPU cores that can be used. This value is + calculated from /sys/fs/cgroup/cpuset/cpuset.cpus + NO_MEMORY_LIMIT + Set to "true" if MEMORY_LIMIT_IN_BYTES is so high that the caller + can act as if no memory limit was set. Undefined otherwise. +""" + +from __future__ import print_function +import sys + + +def _read_file(path): + try: + with open(path, 'r') as f: + return f.read().strip() + except IOError: + return None + + +def get_memory_limit(): + """ + Read memory limit, in bytes. + """ + + limit = _read_file('/sys/fs/cgroup/memory/memory.limit_in_bytes') + if limit is None or not limit.isdigit(): + print("Warning: Can't detect memory limit from cgroups", + file=sys.stderr) + return None + return int(limit) + + +def get_number_of_cores(): + """ + Read number of CPU cores. + """ + + core_count = 0 + + line = _read_file('/sys/fs/cgroup/cpuset/cpuset.cpus') + if line is None: + print("Warning: Can't detect number of CPU cores from cgroups", + file=sys.stderr) + return None + + for group in line.split(','): + core_ids = list(map(int, group.split('-'))) + if len(core_ids) == 2: + core_count += core_ids[1] - core_ids[0] + 1 + else: + core_count += 1 + + return core_count + + +if __name__ == "__main__": + env_vars = { + "MAX_MEMORY_LIMIT_IN_BYTES": 9223372036854775807, + "MEMORY_LIMIT_IN_BYTES": get_memory_limit(), + "NUMBER_OF_CORES": get_number_of_cores() + } + + env_vars = {k: v for k, v in env_vars.items() if v is not None} + + if env_vars.get("MEMORY_LIMIT_IN_BYTES", 0) >= 92233720368547: + env_vars["NO_MEMORY_LIMIT"] = "true" + + for key, value in env_vars.items(): + print("{0}={1}".format(key, value)) \ No newline at end of file diff --git a/bin/fix-permissions b/bin/fix-permissions new file mode 100755 index 0000000..b6ab3fd --- /dev/null +++ b/bin/fix-permissions @@ -0,0 +1,12 @@ +#!/bin/sh + +# Allow this script to fail without failing a build +set +e + +# Fix permissions on the given directory to allow group read/write of +# regular files and execute of directories. +chgrp -R 0 $1; +find -L $1 -xtype l -exec chgrp 0 {} \; +chmod -R g+rw $1; +find -L $1 -xtype l -exec chmod g+rw {} \; +find $1 -type d -exec chmod g+x {} + \ No newline at end of file diff --git a/contrib/etc/httpd.conf b/contrib/etc/httpd.conf new file mode 100644 index 0000000..66dc0fb --- /dev/null +++ b/contrib/etc/httpd.conf @@ -0,0 +1,18 @@ + +LoadModule perl_module modules/mod_perl.so +DirectoryIndex index.pl + +PerlSwitches -I./extlib/lib/perl5 + + + SetHandler perl-script + PerlResponseHandler ModPerl::PerlRun + Options +ExecCGI +SymLinksIfOwnerMatch + PerlSendHeader On + + + + Require all granted + + +IncludeOptional /opt/app-root/etc/httpd.d/*.conf \ No newline at end of file diff --git a/contrib/etc/httpd.d/50-mpm.conf.template b/contrib/etc/httpd.d/50-mpm.conf.template new file mode 100644 index 0000000..ca18659 --- /dev/null +++ b/contrib/etc/httpd.d/50-mpm.conf.template @@ -0,0 +1,11 @@ +# This value should mirror what is set in MinSpareServers. +StartServers ${HTTPD_START_SERVERS} +MinSpareServers ${HTTPD_START_SERVERS} +MaxSpareServers ${HTTPD_MAX_SPARE_SERVERS} +# The MaxRequestWorkers directive sets the limit on the number of +# simultaneous requests that will be served. +# The default value, when no cgroup limits are set is 256. +MaxRequestWorkers ${HTTPD_MAX_REQUEST_WORKERS} +ServerLimit ${HTTPD_MAX_REQUEST_WORKERS} +MaxConnectionsPerChild 4000 +MaxKeepAliveRequests 100 diff --git a/contrib/etc/httpdconf.sed b/contrib/etc/httpdconf.sed new file mode 100644 index 0000000..45f14db --- /dev/null +++ b/contrib/etc/httpdconf.sed @@ -0,0 +1,7 @@ +s/^Listen 80/Listen 0.0.0.0:8080/ +s/^User apache/User default/ +s/^Group apache/Group root/ +s%^DocumentRoot "/var/www/html"%DocumentRoot "/opt/app-root/src"% +s%^" "DATE 11.04.2017" "" +.BR perl (1) +\-\- S2I builder of perl applications +.SH USAGE +.PP +To pull the perl container run: +.PP +.RS +.nf + # docker pull koscicz/perl +.fi +.RE +.PP +To build your perl application use run: +.PP +.RS +.nf + # s2i build koscicz/perl +.fi +.RE +.PP +To run your application in docker container: +.PP +.RS +.nf + # docker run \-p 8080:8080 +.fi +.RE +.SH ENVIROMENT VARIABLES +.PP +To set environment variables, you can place them as a key value pair into a \fB\fC\&.sti/environment\fR +file inside your source code repository. +.PP +ENABLE_CPAN_TEST +.PP +.RS +.nf +Allow the installation of all specified cpan packages and the running of their tests. The default value is `false`. +.fi +.RE +.PP +CPAN_MIRROR +.PP +.RS +.nf +This variable specifies a mirror URL which will used by cpanminus to install dependencies. +By default the URL is not specified. +.fi +.RE +.PP +PERL_APACHE2_RELOAD +.PP +.RS +.nf +Set this to "true" to enable automatic reloading of modified Perl modules. +.fi +.RE +.PP +HTTPD_START_SERVERS +.PP +.RS +.nf +The [StartServers](https://httpd.apache.org/docs/2.4/mod/mpm_common.html#startservers) +directive sets the number of child server processes created on startup. Default is 8. +.fi +.RE +.PP +HTTPD_MAX_REQUEST_WORKERS +.PP +.RS +.nf +Number of simultaneous requests that will be handled by Apache. The default +is 256, but it will be automatically lowered if memory is limited. +.fi +.RE +.PP +PSGI_FILE +.PP +.RS +.nf +Override PSGI application detection. + +If the PSGI_FILE variable is set to empty value, no PSGI application will +be detected and mod_perl not be reconfigured. + +If the PSGI_FILE variable is set and non\-empty, it will define path to +the PSGI application file. No detection will be used. + +If the PSGI_FILE variable does not exist, autodetection will be used: +If exactly one ./*.psgi file exists, mod_perl will be configured to +execute that file. +.fi +.RE +.PP +PSGI_URI_PATH +.PP +.RS +.nf +This variable overrides location URI path that is handled path the PSGI +application. Default value is "/". +.fi +.RE diff --git a/root/help.md b/root/help.md new file mode 100644 index 0000000..bfb35d0 --- /dev/null +++ b/root/help.md @@ -0,0 +1,63 @@ +perl(1) -- S2I builder of perl applications +============================================= + +## USAGE + +To pull the perl container run: + + # docker pull koscicz/perl + +To build your perl application use run: + + # s2i build koscicz/perl + +To run your application in docker container: + + # docker run -p 8080:8080 + +## ENVIROMENT VARIABLES + +To set environment variables, you can place them as a key value pair into a `.sti/environment` +file inside your source code repository. + +ENABLE\_CPAN\_TEST + + Allow the installation of all specified cpan packages and the running of their tests. The default value is `false`. + +CPAN_MIRROR + + This variable specifies a mirror URL which will used by cpanminus to install dependencies. + By default the URL is not specified. + +PERL\_APACHE2\_RELOAD + + Set this to "true" to enable automatic reloading of modified Perl modules. + +HTTPD\_START\_SERVERS + + The [StartServers](https://httpd.apache.org/docs/2.4/mod/mpm_common.html#startservers) + directive sets the number of child server processes created on startup. Default is 8. + +HTTPD\_MAX\_REQUEST\_WORKERS + + Number of simultaneous requests that will be handled by Apache. The default + is 256, but it will be automatically lowered if memory is limited. + +PSGI_FILE + + Override PSGI application detection. + + If the PSGI_FILE variable is set to empty value, no PSGI application will + be detected and mod_perl not be reconfigured. + + If the PSGI_FILE variable is set and non-empty, it will define path to + the PSGI application file. No detection will be used. + + If the PSGI_FILE variable does not exist, autodetection will be used: + If exactly one ./*.psgi file exists, mod_perl will be configured to + execute that file. + +PSGI\_URI\_PATH + + This variable overrides location URI path that is handled path the PSGI + application. Default value is "/". \ No newline at end of file diff --git a/s2i/bin/assemble b/s2i/bin/assemble new file mode 100755 index 0000000..2363d37 --- /dev/null +++ b/s2i/bin/assemble @@ -0,0 +1,76 @@ +#!/bin/bash + +set -e + +shopt -s dotglob +echo "---> Installing application source ..." +mv /tmp/src/* ./ + +if [ -d ./cfg ]; then + echo "---> Copying configuration files..." + if [ "$(ls -A ./cfg/*.conf)" ]; then + cp -v ./cfg/*.conf /opt/app-root/etc/httpd.d/ + fi +fi + +# Allow for http proxy to be specified in uppercase +if [[ -n "${HTTP_PROXY:-}" && -z "${http_proxy:-}" ]]; then + export http_proxy=$HTTP_PROXY +fi + +export CPAN_MIRROR=${CPAN_MIRROR:-""} + +MIRROR_ARGS="" + +if [ -n "$CPAN_MIRROR" ]; then + MIRROR_ARGS="--mirror $CPAN_MIRROR" +fi + +# Don't test installed Perl modules by default +if [ "${ENABLE_CPAN_TEST}" = true ]; then + export ENABLE_CPAN_TEST="" +else + export ENABLE_CPAN_TEST="--notest" +fi + +# Configure mod_perl for PSGI. +# If PSGI_FILE variable is set but empty, skip it. +# If PSGI_FILE is set and non-empty, use it. +# If PSGI_FILE does not exist, check if exactly one ./*.psgi file exists and +# use that file. +# If PSGI_URI_PATH variable has a value, use it as a location. Default is "/". +if [ ! -v PSGI_FILE ]; then + PSGI_FILE=$(find -maxdepth 1 -name '*.psgi' -type f) +fi +PSGI_FILE_NUMBER=$(printf '%s' "$PSGI_FILE" | wc -l) +if [ -n "$PSGI_FILE" -a "$PSGI_FILE_NUMBER" -eq 0 ]; then + echo "---> PSGI application found in $PSGI_FILE" + cat >> cpanfile <<"EOF" +requires 'Plack::Handler::Apache2'; +EOF + # XXX: Escape PSGI_FILE value against httpd control characters + PSGI_FILE=$(printf '%s' "$PSGI_FILE" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g') + cat > /opt/app-root/etc/httpd.d/40-psgi.conf < + SetHandler perl-script + PerlResponseHandler Plack::Handler::Apache2 + PerlSetVar psgi_app "$PSGI_FILE" + +EOF +elif [ "$PSGI_FILE_NUMBER" -gt 0 ]; then + echo "---> Multiple PSGI applications found:" + printf '%s' "$PSGI_FILE" + echo "---> Skipping PSGI autoconfiguration!" +fi + +# Installing dependencies with cpanfile +if [ -f "cpanfile" ]; then + echo "---> Installing modules from cpanfile ..." + cpanm $MIRROR_ARGS $ENABLE_CPAN_TEST -l extlib Module::CoreList + cpanm $MIRROR_ARGS $ENABLE_CPAN_TEST -l extlib --installdeps . +else + echo "---> No cpanfile found, nothing to install" +fi + +# Fix source directory permissions +fix-permissions ./ \ No newline at end of file diff --git a/s2i/bin/run b/s2i/bin/run new file mode 100755 index 0000000..687feb1 --- /dev/null +++ b/s2i/bin/run @@ -0,0 +1,46 @@ +#!/bin/bash + +set -e + +# CPAN can install scripts. They should be available from mod_perl too. +export PATH=${PATH}:/opt/app-root/src/extlib/bin +# And we have to set Perl include path too because mod_perl's PerlSwitches +# does not apply to them. +export PERL5LIB=/opt/app-root/src/extlib/lib/perl5 + +# Warning: Please note that this will pass all environment variables available within the +# container to mod_perl by means of PerlPassEnv in the env.conf file +if [ ! -f /opt/app-root/etc/httpd.d/env.conf ]; then + env | awk -F'=' '{print "PerlPassEnv "$1}' > /opt/app-root/etc/httpd.d/env.conf +fi + +# Enable automatic reloading. This can be useful for debugging an application. +PERL_APACHE2_RELOAD=${PERL_APACHE2_RELOAD:-} +if [[ "${PERL_APACHE2_RELOAD,,}" == "true" ]]; then + cat > /opt/app-root/etc/httpd.d/50-autoreload.conf < 0 ? MAX_SERVER_LIMIT : 1)) + export HTTPD_MAX_REQUEST_WORKERS=$((MAX_SERVER_LIMIT > 256 ? 256 : MAX_SERVER_LIMIT)) +fi + +export HTTPD_START_SERVERS=${HTTPD_START_SERVERS:-8} +export HTTPD_MAX_SPARE_SERVERS=$((HTTPD_START_SERVERS+10)) + +envsubst < /opt/app-root/etc/httpd.d/50-mpm.conf.template > /opt/app-root/etc/httpd.d/50-mpm.conf + +exec httpd -C 'Include /opt/app-root/etc/httpd.conf' -D FOREGROUND \ No newline at end of file diff --git a/s2i/bin/usage b/s2i/bin/usage new file mode 100755 index 0000000..ddfa51b --- /dev/null +++ b/s2i/bin/usage @@ -0,0 +1,11 @@ + +#!/bin/sh + +cat < Date: Mon, 24 Apr 2017 16:39:39 +0200 Subject: [PATCH 2/6] Initial commit --- Dockerfile | 74 +++++++++++++ README.md | 124 +++++++++++++++++++++ bin/cgroup-limits | 92 ++++++++++++++++ bin/fix-permissions | 12 +++ contrib/etc/httpd.conf | 18 ++++ contrib/etc/httpd.d/50-mpm.conf.template | 11 ++ contrib/etc/httpdconf.sed | 7 ++ openshift-template.yml | 130 +++++++++++++++++++++++ repos/fedora.repo | 5 + repos/perl.repo | 5 + root/help.1 | 102 ++++++++++++++++++ root/help.md | 63 +++++++++++ s2i/bin/assemble | 76 +++++++++++++ s2i/bin/run | 46 ++++++++ s2i/bin/usage | 11 ++ 15 files changed, 776 insertions(+) create mode 100644 Dockerfile create mode 100644 README.md create mode 100755 bin/cgroup-limits create mode 100755 bin/fix-permissions create mode 100644 contrib/etc/httpd.conf create mode 100644 contrib/etc/httpd.d/50-mpm.conf.template create mode 100644 contrib/etc/httpdconf.sed create mode 100644 openshift-template.yml create mode 100644 repos/fedora.repo create mode 100644 repos/perl.repo create mode 100644 root/help.1 create mode 100644 root/help.md create mode 100755 s2i/bin/assemble create mode 100755 s2i/bin/run create mode 100755 s2i/bin/usage diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9ad5ad0 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,74 @@ +FROM baseruntime/baseruntime:latest + +# Port on which will apache run +EXPOSE 8080 + +# Image metadata +ENV NAME=perl \ + PERL_VERSION=5.24 \ + VERSION=0 \ + RELEASE=1 \ + ARCH=x86_64 + +# Set labels used in OpenShift to describe the builder images +LABEL com.redhat.component="$NAME" \ + name="$FGC/$NAME" \ + summary="Perl 5 is a highly capable, feature-rich programming language." \ + description="Perl 5 is a highly capable, feature-rich programming language with over 29 years of development. Perl 5 runs on over 100 platforms." \ + version="$VERSION" \ + release="$RELEASE.$DISTTAG" \ + architecture="$ARCH" \ + usage="s2i build file:///your/app modularitycontainers/perl your-app" \ + io.k8s.description="Platform for building and running Perl 5.24 applications" \ + io.k8s.display-name="Apache 2.4 with mod_perl/5.24" \ + io.openshift.expose-services="8080:http" \ + io.openshift.tags="builder,perl,perl524" \ + io.openshift.s2i.scripts-url=image:///usr/local/s2i + + +COPY repos/* /etc/yum.repos.d/ + +# Perl and build tools install + user addition +RUN BUILD_TOOlS="bsdtar \ + findutils \ + gcc \ + make \ + gettext \ + tar \ + wget \ + python " && \ + microdnf --nodocs --enablerepo perl install perl perl-devel && \ + microdnf --nodocs --enablerepo fedora install -y mod_perl cpan cpanminus httpd \ + $BUILD_TOOlS && \ + microdnf clean all +RUN mkdir -p /opt/app-root/src/ && \ + useradd -u 1002 -r -g 0 -d /opt/app-root/src -s /sbin/nologin \ + -c "Default Application User" default && \ + chown -R 1002:0 /opt/app-root + +# Copy s2i files +COPY ./s2i/bin/ /usr/local/s2i + +# Copy apache configuration +COPY ./contrib/ /opt/app-root + +# Drop the root user +RUN mkdir -p /opt/app-root/etc/httpd.d && \ + sed -i -f /opt/app-root/etc/httpdconf.sed etc/httpd/conf/httpd.conf && \ + chmod -R og+rwx /var/run/httpd /opt/app-root/etc/httpd.d && \ + chown -R 1002:0 /opt/app-root && chmod -R ug+rwx /opt/app-root + +USER 1002 + +# Copy executable utilities. +COPY bin/ /usr/bin/ + +# Copy help file +COPY root/help.1 / + +# Directory with the sources is set as the working directory so all STI scripts +# can execute relative to this path. +WORKDIR /opt/app-root/src + +# Set the default command to print the usage +CMD /usr/local/s2i/usage diff --git a/README.md b/README.md new file mode 100644 index 0000000..458f843 --- /dev/null +++ b/README.md @@ -0,0 +1,124 @@ +# Perl S2I +This repository contains the sources for S2I builder image for perl 5.24 as well as some sample applications. This is a port to Fedora of software collections Perl located [here](https://github.com/sclorg/s2i-perl-container), that is now using base-runtime and Perl module. Please note that this solution uses httpd 2.4 to display results. + +# Usage +## Docker +First you need to build the builder image. After you have the builder image, you can use it for a S2I build. You can build and run the sample app like this: +``` +$ docker build --tag=koscicz/perl . +$ s2i build https://github.com/container-images/perl.git --context-dir=test/sample-test-app/ koscicz/perl perl-sample-app +$ docker run -p 8080:8080 perl-sample-app +``` +This will build and run you application on 127.0.0.1:8080. You can also build the builder image by running `make`. This will also tag your image as koscicz/perl. + +## Openshift +You can use the `openshift-template.yml` in this repository to run your application in Openshift. You can either use web interface, in which case you'll just have to fill out a form, requiring a source repository for your app and name of this app. In case you want to use cli, you can do it like this, after you login: +``` +$ oc new-project perl-test +$ oc new-app https://raw.githubusercontent.com/container-images/perl/master/openshift-template.yml -p APP_NAME="perl-example" -p SOURCE_REPOSITORY="https://github.com/kosciCZ/perl-example" +``` +These commands will build the sample application on your Openshift platform. + +# Testing +This repository contains a `test` folder with some tests to ensure proper functionality. You can run test by using Makefile. You have two options: +* `make all` This will build, tag and test the image +* `make test` This will run the test on the image, that is defined in the Makefile. By default it is koscicz/perl +Or you can execute the test script directly, as described below in [Repository organization](#repository-organization) + +Repository organization +------------------------ +* **Dockerfile** + + Fedora based Dockerfile. + +* **`s2i/bin/`** + + This folder contains scripts that are run by [S2I](https://github.com/openshift/source-to-image): + + * **assemble** + + Used to install the sources into a location where the application + will be run and prepare the application for deployment (eg. installing + modules, etc.). + In order to install application dependencies, the application must contain a + `cpanfile` file, in which the user specifies the modules and their versions. + An example of a [cpanfile](https://github.com/container-images/perl/blob/master/test/sample-test-app/cpanfile) is available within our test application. + + All files with `.cgi` and `.pl` extension are handled by mod_perl. + If exactly one file with `.psgi` extension exists in the top-level + directory, the mod_perl will be autoconfigured to execute the PSGI + application for any request URI path with Plack's mod_perl adaptor. + + * **run** + + This script is responsible for running the application, using the + Apache web server. + + * **usage*** + + This script prints the usage of this image. + +* **`contrib/`** + + This folder contains a file with commonly used modules. + +* **`test/`** + + This folder contains some sample applications you can use to test you image. + + * **`sample-test-app/`** + + A simple Perl application used for testing purposes by the [S2I](https://github.com/openshift/source-to-image) test framework. + + * **run** + + This is a script that runs a test suite on the builder image, to ensure it has all the necessary functionality. + Run it by `./run IMAGE`, where `IMAGE` is your builder image. + +Environment variables +--------------------- + +To set environment variables, you can place them as a key value pair into a `.sti/environment` +file inside your source code repository. + +* **ENABLE_CPAN_TEST** + + Allow the installation of all specified cpan packages and the running of their tests. The default value is `false`. + +* **CPAN_MIRROR** + + This variable specifies a mirror URL which will used by cpanminus to install dependencies. + By default the URL is not specified. + +* **PERL_APACHE2_RELOAD** + + Set this to "true" to enable automatic reloading of modified Perl modules. + +* **HTTPD_START_SERVERS** + + The [StartServers](https://httpd.apache.org/docs/2.4/mod/mpm_common.html#startservers) + directive sets the number of child server processes created on startup. Default is 8. + +* **HTTPD_MAX_REQUEST_WORKERS** + + Number of simultaneous requests that will be handled by Apache. The default + is 256, but it will be automatically lowered if memory is limited. + +* **PSGI_FILE** + + Override PSGI application detection. + + If the PSGI_FILE variable is set to empty value, no PSGI application will + be detected and mod_perl not be reconfigured. + + If the PSGI_FILE variable is set and non-empty, it will define path to + the PSGI application file. No detection will be used. + + If the PSGI_FILE variable does not exist, autodetection will be used: + If exactly one ./*.psgi file exists, mod_perl will be configured to + execute that file. + +* **PSGI_URI_PATH** + + This variable overrides location URI path that is handled path the PSGI + application. Default value is "/". \ No newline at end of file diff --git a/bin/cgroup-limits b/bin/cgroup-limits new file mode 100755 index 0000000..3107fbf --- /dev/null +++ b/bin/cgroup-limits @@ -0,0 +1,92 @@ +#!/usr/bin/python + +""" +Script for parsing cgroup information + +This script will read some limits from the cgroup system and parse +them, printing out "VARIABLE=VALUE" on each line for every limit that is +successfully read. Output of this script can be directly fed into +bash's export command. Recommended usage from a bash script: + + set -o errexit + export_vars=$(cgroup-limits) ; export $export_vars + +Variables currently supported: + MAX_MEMORY_LIMIT_IN_BYTES + Maximum possible limit MEMORY_LIMIT_IN_BYTES can have. This is + currently constant value of 9223372036854775807. + MEMORY_LIMIT_IN_BYTES + Maximum amount of user memory in bytes. If this value is set + to the same value as MAX_MEMORY_LIMIT_IN_BYTES, it means that + there is no limit set. The value is taken from + /sys/fs/cgroup/memory/memory.limit_in_bytes + NUMBER_OF_CORES + Number of detected CPU cores that can be used. This value is + calculated from /sys/fs/cgroup/cpuset/cpuset.cpus + NO_MEMORY_LIMIT + Set to "true" if MEMORY_LIMIT_IN_BYTES is so high that the caller + can act as if no memory limit was set. Undefined otherwise. +""" + +from __future__ import print_function +import sys + + +def _read_file(path): + try: + with open(path, 'r') as f: + return f.read().strip() + except IOError: + return None + + +def get_memory_limit(): + """ + Read memory limit, in bytes. + """ + + limit = _read_file('/sys/fs/cgroup/memory/memory.limit_in_bytes') + if limit is None or not limit.isdigit(): + print("Warning: Can't detect memory limit from cgroups", + file=sys.stderr) + return None + return int(limit) + + +def get_number_of_cores(): + """ + Read number of CPU cores. + """ + + core_count = 0 + + line = _read_file('/sys/fs/cgroup/cpuset/cpuset.cpus') + if line is None: + print("Warning: Can't detect number of CPU cores from cgroups", + file=sys.stderr) + return None + + for group in line.split(','): + core_ids = list(map(int, group.split('-'))) + if len(core_ids) == 2: + core_count += core_ids[1] - core_ids[0] + 1 + else: + core_count += 1 + + return core_count + + +if __name__ == "__main__": + env_vars = { + "MAX_MEMORY_LIMIT_IN_BYTES": 9223372036854775807, + "MEMORY_LIMIT_IN_BYTES": get_memory_limit(), + "NUMBER_OF_CORES": get_number_of_cores() + } + + env_vars = {k: v for k, v in env_vars.items() if v is not None} + + if env_vars.get("MEMORY_LIMIT_IN_BYTES", 0) >= 92233720368547: + env_vars["NO_MEMORY_LIMIT"] = "true" + + for key, value in env_vars.items(): + print("{0}={1}".format(key, value)) \ No newline at end of file diff --git a/bin/fix-permissions b/bin/fix-permissions new file mode 100755 index 0000000..b6ab3fd --- /dev/null +++ b/bin/fix-permissions @@ -0,0 +1,12 @@ +#!/bin/sh + +# Allow this script to fail without failing a build +set +e + +# Fix permissions on the given directory to allow group read/write of +# regular files and execute of directories. +chgrp -R 0 $1; +find -L $1 -xtype l -exec chgrp 0 {} \; +chmod -R g+rw $1; +find -L $1 -xtype l -exec chmod g+rw {} \; +find $1 -type d -exec chmod g+x {} + \ No newline at end of file diff --git a/contrib/etc/httpd.conf b/contrib/etc/httpd.conf new file mode 100644 index 0000000..66dc0fb --- /dev/null +++ b/contrib/etc/httpd.conf @@ -0,0 +1,18 @@ + +LoadModule perl_module modules/mod_perl.so +DirectoryIndex index.pl + +PerlSwitches -I./extlib/lib/perl5 + + + SetHandler perl-script + PerlResponseHandler ModPerl::PerlRun + Options +ExecCGI +SymLinksIfOwnerMatch + PerlSendHeader On + + + + Require all granted + + +IncludeOptional /opt/app-root/etc/httpd.d/*.conf \ No newline at end of file diff --git a/contrib/etc/httpd.d/50-mpm.conf.template b/contrib/etc/httpd.d/50-mpm.conf.template new file mode 100644 index 0000000..ca18659 --- /dev/null +++ b/contrib/etc/httpd.d/50-mpm.conf.template @@ -0,0 +1,11 @@ +# This value should mirror what is set in MinSpareServers. +StartServers ${HTTPD_START_SERVERS} +MinSpareServers ${HTTPD_START_SERVERS} +MaxSpareServers ${HTTPD_MAX_SPARE_SERVERS} +# The MaxRequestWorkers directive sets the limit on the number of +# simultaneous requests that will be served. +# The default value, when no cgroup limits are set is 256. +MaxRequestWorkers ${HTTPD_MAX_REQUEST_WORKERS} +ServerLimit ${HTTPD_MAX_REQUEST_WORKERS} +MaxConnectionsPerChild 4000 +MaxKeepAliveRequests 100 diff --git a/contrib/etc/httpdconf.sed b/contrib/etc/httpdconf.sed new file mode 100644 index 0000000..45f14db --- /dev/null +++ b/contrib/etc/httpdconf.sed @@ -0,0 +1,7 @@ +s/^Listen 80/Listen 0.0.0.0:8080/ +s/^User apache/User default/ +s/^Group apache/Group root/ +s%^DocumentRoot "/var/www/html"%DocumentRoot "/opt/app-root/src"% +s%^" "DATE 11.04.2017" "" +.BR perl (1) +\-\- S2I builder of perl applications +.SH USAGE +.PP +To pull the perl container run: +.PP +.RS +.nf + # docker pull koscicz/perl +.fi +.RE +.PP +To build your perl application use run: +.PP +.RS +.nf + # s2i build koscicz/perl +.fi +.RE +.PP +To run your application in docker container: +.PP +.RS +.nf + # docker run \-p 8080:8080 +.fi +.RE +.SH ENVIROMENT VARIABLES +.PP +To set environment variables, you can place them as a key value pair into a \fB\fC\&.sti/environment\fR +file inside your source code repository. +.PP +ENABLE_CPAN_TEST +.PP +.RS +.nf +Allow the installation of all specified cpan packages and the running of their tests. The default value is `false`. +.fi +.RE +.PP +CPAN_MIRROR +.PP +.RS +.nf +This variable specifies a mirror URL which will used by cpanminus to install dependencies. +By default the URL is not specified. +.fi +.RE +.PP +PERL_APACHE2_RELOAD +.PP +.RS +.nf +Set this to "true" to enable automatic reloading of modified Perl modules. +.fi +.RE +.PP +HTTPD_START_SERVERS +.PP +.RS +.nf +The [StartServers](https://httpd.apache.org/docs/2.4/mod/mpm_common.html#startservers) +directive sets the number of child server processes created on startup. Default is 8. +.fi +.RE +.PP +HTTPD_MAX_REQUEST_WORKERS +.PP +.RS +.nf +Number of simultaneous requests that will be handled by Apache. The default +is 256, but it will be automatically lowered if memory is limited. +.fi +.RE +.PP +PSGI_FILE +.PP +.RS +.nf +Override PSGI application detection. + +If the PSGI_FILE variable is set to empty value, no PSGI application will +be detected and mod_perl not be reconfigured. + +If the PSGI_FILE variable is set and non\-empty, it will define path to +the PSGI application file. No detection will be used. + +If the PSGI_FILE variable does not exist, autodetection will be used: +If exactly one ./*.psgi file exists, mod_perl will be configured to +execute that file. +.fi +.RE +.PP +PSGI_URI_PATH +.PP +.RS +.nf +This variable overrides location URI path that is handled path the PSGI +application. Default value is "/". +.fi +.RE diff --git a/root/help.md b/root/help.md new file mode 100644 index 0000000..bfb35d0 --- /dev/null +++ b/root/help.md @@ -0,0 +1,63 @@ +perl(1) -- S2I builder of perl applications +============================================= + +## USAGE + +To pull the perl container run: + + # docker pull koscicz/perl + +To build your perl application use run: + + # s2i build koscicz/perl + +To run your application in docker container: + + # docker run -p 8080:8080 + +## ENVIROMENT VARIABLES + +To set environment variables, you can place them as a key value pair into a `.sti/environment` +file inside your source code repository. + +ENABLE\_CPAN\_TEST + + Allow the installation of all specified cpan packages and the running of their tests. The default value is `false`. + +CPAN_MIRROR + + This variable specifies a mirror URL which will used by cpanminus to install dependencies. + By default the URL is not specified. + +PERL\_APACHE2\_RELOAD + + Set this to "true" to enable automatic reloading of modified Perl modules. + +HTTPD\_START\_SERVERS + + The [StartServers](https://httpd.apache.org/docs/2.4/mod/mpm_common.html#startservers) + directive sets the number of child server processes created on startup. Default is 8. + +HTTPD\_MAX\_REQUEST\_WORKERS + + Number of simultaneous requests that will be handled by Apache. The default + is 256, but it will be automatically lowered if memory is limited. + +PSGI_FILE + + Override PSGI application detection. + + If the PSGI_FILE variable is set to empty value, no PSGI application will + be detected and mod_perl not be reconfigured. + + If the PSGI_FILE variable is set and non-empty, it will define path to + the PSGI application file. No detection will be used. + + If the PSGI_FILE variable does not exist, autodetection will be used: + If exactly one ./*.psgi file exists, mod_perl will be configured to + execute that file. + +PSGI\_URI\_PATH + + This variable overrides location URI path that is handled path the PSGI + application. Default value is "/". \ No newline at end of file diff --git a/s2i/bin/assemble b/s2i/bin/assemble new file mode 100755 index 0000000..2363d37 --- /dev/null +++ b/s2i/bin/assemble @@ -0,0 +1,76 @@ +#!/bin/bash + +set -e + +shopt -s dotglob +echo "---> Installing application source ..." +mv /tmp/src/* ./ + +if [ -d ./cfg ]; then + echo "---> Copying configuration files..." + if [ "$(ls -A ./cfg/*.conf)" ]; then + cp -v ./cfg/*.conf /opt/app-root/etc/httpd.d/ + fi +fi + +# Allow for http proxy to be specified in uppercase +if [[ -n "${HTTP_PROXY:-}" && -z "${http_proxy:-}" ]]; then + export http_proxy=$HTTP_PROXY +fi + +export CPAN_MIRROR=${CPAN_MIRROR:-""} + +MIRROR_ARGS="" + +if [ -n "$CPAN_MIRROR" ]; then + MIRROR_ARGS="--mirror $CPAN_MIRROR" +fi + +# Don't test installed Perl modules by default +if [ "${ENABLE_CPAN_TEST}" = true ]; then + export ENABLE_CPAN_TEST="" +else + export ENABLE_CPAN_TEST="--notest" +fi + +# Configure mod_perl for PSGI. +# If PSGI_FILE variable is set but empty, skip it. +# If PSGI_FILE is set and non-empty, use it. +# If PSGI_FILE does not exist, check if exactly one ./*.psgi file exists and +# use that file. +# If PSGI_URI_PATH variable has a value, use it as a location. Default is "/". +if [ ! -v PSGI_FILE ]; then + PSGI_FILE=$(find -maxdepth 1 -name '*.psgi' -type f) +fi +PSGI_FILE_NUMBER=$(printf '%s' "$PSGI_FILE" | wc -l) +if [ -n "$PSGI_FILE" -a "$PSGI_FILE_NUMBER" -eq 0 ]; then + echo "---> PSGI application found in $PSGI_FILE" + cat >> cpanfile <<"EOF" +requires 'Plack::Handler::Apache2'; +EOF + # XXX: Escape PSGI_FILE value against httpd control characters + PSGI_FILE=$(printf '%s' "$PSGI_FILE" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g') + cat > /opt/app-root/etc/httpd.d/40-psgi.conf < + SetHandler perl-script + PerlResponseHandler Plack::Handler::Apache2 + PerlSetVar psgi_app "$PSGI_FILE" + +EOF +elif [ "$PSGI_FILE_NUMBER" -gt 0 ]; then + echo "---> Multiple PSGI applications found:" + printf '%s' "$PSGI_FILE" + echo "---> Skipping PSGI autoconfiguration!" +fi + +# Installing dependencies with cpanfile +if [ -f "cpanfile" ]; then + echo "---> Installing modules from cpanfile ..." + cpanm $MIRROR_ARGS $ENABLE_CPAN_TEST -l extlib Module::CoreList + cpanm $MIRROR_ARGS $ENABLE_CPAN_TEST -l extlib --installdeps . +else + echo "---> No cpanfile found, nothing to install" +fi + +# Fix source directory permissions +fix-permissions ./ \ No newline at end of file diff --git a/s2i/bin/run b/s2i/bin/run new file mode 100755 index 0000000..687feb1 --- /dev/null +++ b/s2i/bin/run @@ -0,0 +1,46 @@ +#!/bin/bash + +set -e + +# CPAN can install scripts. They should be available from mod_perl too. +export PATH=${PATH}:/opt/app-root/src/extlib/bin +# And we have to set Perl include path too because mod_perl's PerlSwitches +# does not apply to them. +export PERL5LIB=/opt/app-root/src/extlib/lib/perl5 + +# Warning: Please note that this will pass all environment variables available within the +# container to mod_perl by means of PerlPassEnv in the env.conf file +if [ ! -f /opt/app-root/etc/httpd.d/env.conf ]; then + env | awk -F'=' '{print "PerlPassEnv "$1}' > /opt/app-root/etc/httpd.d/env.conf +fi + +# Enable automatic reloading. This can be useful for debugging an application. +PERL_APACHE2_RELOAD=${PERL_APACHE2_RELOAD:-} +if [[ "${PERL_APACHE2_RELOAD,,}" == "true" ]]; then + cat > /opt/app-root/etc/httpd.d/50-autoreload.conf < 0 ? MAX_SERVER_LIMIT : 1)) + export HTTPD_MAX_REQUEST_WORKERS=$((MAX_SERVER_LIMIT > 256 ? 256 : MAX_SERVER_LIMIT)) +fi + +export HTTPD_START_SERVERS=${HTTPD_START_SERVERS:-8} +export HTTPD_MAX_SPARE_SERVERS=$((HTTPD_START_SERVERS+10)) + +envsubst < /opt/app-root/etc/httpd.d/50-mpm.conf.template > /opt/app-root/etc/httpd.d/50-mpm.conf + +exec httpd -C 'Include /opt/app-root/etc/httpd.conf' -D FOREGROUND \ No newline at end of file diff --git a/s2i/bin/usage b/s2i/bin/usage new file mode 100755 index 0000000..ddfa51b --- /dev/null +++ b/s2i/bin/usage @@ -0,0 +1,11 @@ + +#!/bin/sh + +cat < Date: Mon, 24 Apr 2017 16:57:14 +0200 Subject: [PATCH 3/6] Fix registry for base-runtime --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 9ad5ad0..5acb6f4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM baseruntime/baseruntime:latest +FROM docker.io/baseruntime/baseruntime:latest # Port on which will apache run EXPOSE 8080 From f4e272812fcf875b231e0bc6da9b610a8f2a8484 Mon Sep 17 00:00:00 2001 From: Jiri Popelka Date: Tue, 12 Jun 2018 18:56:29 +0200 Subject: [PATCH 4/6] Use fedora:28 base image --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 0a3f058..107c5bc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM registry.fedoraproject.org/fedora:25 +FROM registry.fedoraproject.org/fedora:28 # Port on which will apache run EXPOSE 8080 From 0f80dc1c6f82a436f5fefc7709022f838e742538 Mon Sep 17 00:00:00 2001 From: Clement Verna Date: Mon, 27 Aug 2018 10:05:30 +0200 Subject: [PATCH 5/6] Drop Release label in favor of OSBS release_bump plugin. OSBS can automatically bump the release number, for that we just need to drop the label from the Dockerfile See https://pagure.io/ContainerSIG/container-sig/issue/1 Signed-off-by: Clement Verna --- Dockerfile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 107c5bc..e3a2900 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM registry.fedoraproject.org/fedora:28 +FROM registry.fedoraproject.org/fedora:rawhide # Port on which will apache run EXPOSE 8080 @@ -7,7 +7,6 @@ EXPOSE 8080 ENV NAME=perl \ PERL_VERSION=5.24 \ VERSION=0 \ - RELEASE=1 \ ARCH=x86_64 # Set labels used in OpenShift to describe the builder images @@ -16,7 +15,6 @@ LABEL com.redhat.component="$NAME" \ summary="Perl 5 is a highly capable, feature-rich programming language." \ description="Perl 5 is a highly capable, feature-rich programming language with over 29 years of development. Perl 5 runs on over 100 platforms." \ version="$VERSION" \ - release="$RELEASE.$DISTTAG" \ architecture="$ARCH" \ usage="s2i build file:///your/app modularitycontainers/perl your-app" \ io.k8s.description="Platform for building and running Perl 5.24 applications" \ From 032270168869a857d5a45e8372659e8998375b04 Mon Sep 17 00:00:00 2001 From: Honza Horak Date: Tue, 8 Jul 2025 17:39:51 +0200 Subject: [PATCH 6/6] container sources not used for building fedora containers anymore --- .gitignore | 0 Dockerfile | 69 ------------ README.md | 124 --------------------- bin/cgroup-limits | 92 ---------------- bin/fix-permissions | 12 --- contrib/etc/httpd.conf | 18 ---- contrib/etc/httpd.d/50-mpm.conf.template | 11 -- contrib/etc/httpdconf.sed | 7 -- dead.package | 1 + openshift-template.yml | 130 ----------------------- root/help.1 | 102 ------------------ root/help.md | 63 ----------- s2i/bin/assemble | 76 ------------- s2i/bin/run | 46 -------- s2i/bin/usage | 11 -- sources | 0 16 files changed, 1 insertion(+), 761 deletions(-) delete mode 100644 .gitignore delete mode 100644 Dockerfile delete mode 100644 README.md delete mode 100755 bin/cgroup-limits delete mode 100755 bin/fix-permissions delete mode 100644 contrib/etc/httpd.conf delete mode 100644 contrib/etc/httpd.d/50-mpm.conf.template delete mode 100644 contrib/etc/httpdconf.sed create mode 100644 dead.package delete mode 100644 openshift-template.yml delete mode 100644 root/help.1 delete mode 100644 root/help.md delete mode 100755 s2i/bin/assemble delete mode 100755 s2i/bin/run delete mode 100755 s2i/bin/usage delete mode 100644 sources diff --git a/.gitignore b/.gitignore deleted file mode 100644 index e69de29..0000000 diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index e3a2900..0000000 --- a/Dockerfile +++ /dev/null @@ -1,69 +0,0 @@ -FROM registry.fedoraproject.org/fedora:rawhide - -# Port on which will apache run -EXPOSE 8080 - -# Image metadata -ENV NAME=perl \ - PERL_VERSION=5.24 \ - VERSION=0 \ - ARCH=x86_64 - -# Set labels used in OpenShift to describe the builder images -LABEL com.redhat.component="$NAME" \ - name="$FGC/$NAME" \ - summary="Perl 5 is a highly capable, feature-rich programming language." \ - description="Perl 5 is a highly capable, feature-rich programming language with over 29 years of development. Perl 5 runs on over 100 platforms." \ - version="$VERSION" \ - architecture="$ARCH" \ - usage="s2i build file:///your/app modularitycontainers/perl your-app" \ - io.k8s.description="Platform for building and running Perl 5.24 applications" \ - io.k8s.display-name="Apache 2.4 with mod_perl/5.24" \ - io.openshift.expose-services="8080:http" \ - io.openshift.tags="builder,perl,perl524" \ - io.openshift.s2i.scripts-url=image:///usr/local/s2i - -# Perl and build tools install + user addition - -RUN BUILD_TOOlS="bsdtar \ - findutils \ - gcc \ - make \ - gettext \ - tar \ - wget \ - python " && \ - dnf install -y --setopt=tsflags=nodocs perl perl-devel mod_perl cpan cpanminus httpd \ - $BUILD_TOOlS && \ - dnf clean all && \ - mkdir -p /opt/app-root/src/ && \ - useradd -u 1001 -r -g 0 -d /opt/app-root/src -s /sbin/nologin \ - -c "Default Application User" default && \ - chown -R 1001:0 /opt/app-root - -# Copy s2i files -COPY ./s2i/bin/ /usr/local/s2i - -# Copy apache configuration -COPY ./contrib/ /opt/app-root - -# Drop the root user -RUN mkdir -p /opt/app-root/etc/httpd.d && \ - sed -i -f /opt/app-root/etc/httpdconf.sed etc/httpd/conf/httpd.conf && \ - chmod -R og+rwx /var/run/httpd /opt/app-root/etc/httpd.d && \ - chown -R 1001:0 /opt/app-root && chmod -R ug+rwx /opt/app-root - -USER 1001 - -# Copy executable utilities. -COPY bin/ /usr/bin/ - -# Copy help file -COPY root/help.1 / - -# Directory with the sources is set as the working directory so all STI scripts -# can execute relative to this path. -WORKDIR /opt/app-root/src - -# Set the default command to print the usage -CMD /usr/local/s2i/usage diff --git a/README.md b/README.md deleted file mode 100644 index 06cfba0..0000000 --- a/README.md +++ /dev/null @@ -1,124 +0,0 @@ -# Perl S2I -This repository contains the sources for S2I builder image for perl 5.24 as well as some sample applications. This is a port to Fedora of software collections Perl located [here](https://github.com/sclorg/s2i-perl-container). Please note that this solution uses httpd 2.4 to display results. - -# Usage -## Docker -First you need to build the builder image. After you have the builder image, you can use it for a S2I build. You can build and run the sample app like this: -``` -$ docker build --tag=koscicz/perl . -$ s2i build https://github.com/container-images/perl.git --context-dir=test/sample-test-app/ koscicz/perl perl-sample-app -$ docker run -p 8080:8080 perl-sample-app -``` -This will build and run you application on 127.0.0.1:8080. You can also build the builder image by running `make`. This will also tag your image as koscicz/perl. - -## Openshift -You can use the `openshift-template.yml` in this repository to run your application in Openshift. You can either use web interface, in which case you'll just have to fill out a form, requiring a source repository for your app and name of this app. In case you want to use cli, you can do it like this, after you login: -``` -$ oc new-project perl-test -$ oc new-app https://raw.githubusercontent.com/container-images/perl/master/openshift-template.yml -p APP_NAME="perl-example" -p SOURCE_REPOSITORY="https://github.com/kosciCZ/perl-example" -``` -These commands will build the sample application on your Openshift platform. - -# Testing -This repository contains a `test` folder with some tests to ensure proper functionality. You can run test by using Makefile. You have two options: -* `make all` This will build, tag and test the image -* `make test` This will run the test on the image, that is defined in the Makefile. By default it is koscicz/perl -Or you can execute the test script directly, as described below in [Repository organization](#repository-organization) - -Repository organization ------------------------- -* **Dockerfile** - - Fedora based Dockerfile. - -* **`s2i/bin/`** - - This folder contains scripts that are run by [S2I](https://github.com/openshift/source-to-image): - - * **assemble** - - Used to install the sources into a location where the application - will be run and prepare the application for deployment (eg. installing - modules, etc.). - In order to install application dependencies, the application must contain a - `cpanfile` file, in which the user specifies the modules and their versions. - An example of a [cpanfile](https://github.com/container-images/perl/blob/master/test/sample-test-app/cpanfile) is available within our test application. - - All files with `.cgi` and `.pl` extension are handled by mod_perl. - If exactly one file with `.psgi` extension exists in the top-level - directory, the mod_perl will be autoconfigured to execute the PSGI - application for any request URI path with Plack's mod_perl adaptor. - - * **run** - - This script is responsible for running the application, using the - Apache web server. - - * **usage*** - - This script prints the usage of this image. - -* **`contrib/`** - - This folder contains a file with commonly used modules. - -* **`test/`** - - This folder contains some sample applications you can use to test you image. - - * **`sample-test-app/`** - - A simple Perl application used for testing purposes by the [S2I](https://github.com/openshift/source-to-image) test framework. - - * **run** - - This is a script that runs a test suite on the builder image, to ensure it has all the necessary functionality. - Run it by `./run IMAGE`, where `IMAGE` is your builder image. - -Environment variables ---------------------- - -To set environment variables, you can place them as a key value pair into a `.sti/environment` -file inside your source code repository. - -* **ENABLE_CPAN_TEST** - - Allow the installation of all specified cpan packages and the running of their tests. The default value is `false`. - -* **CPAN_MIRROR** - - This variable specifies a mirror URL which will used by cpanminus to install dependencies. - By default the URL is not specified. - -* **PERL_APACHE2_RELOAD** - - Set this to "true" to enable automatic reloading of modified Perl modules. - -* **HTTPD_START_SERVERS** - - The [StartServers](https://httpd.apache.org/docs/2.4/mod/mpm_common.html#startservers) - directive sets the number of child server processes created on startup. Default is 8. - -* **HTTPD_MAX_REQUEST_WORKERS** - - Number of simultaneous requests that will be handled by Apache. The default - is 256, but it will be automatically lowered if memory is limited. - -* **PSGI_FILE** - - Override PSGI application detection. - - If the PSGI_FILE variable is set to empty value, no PSGI application will - be detected and mod_perl not be reconfigured. - - If the PSGI_FILE variable is set and non-empty, it will define path to - the PSGI application file. No detection will be used. - - If the PSGI_FILE variable does not exist, autodetection will be used: - If exactly one ./*.psgi file exists, mod_perl will be configured to - execute that file. - -* **PSGI_URI_PATH** - - This variable overrides location URI path that is handled path the PSGI - application. Default value is "/". \ No newline at end of file diff --git a/bin/cgroup-limits b/bin/cgroup-limits deleted file mode 100755 index 3107fbf..0000000 --- a/bin/cgroup-limits +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/python - -""" -Script for parsing cgroup information - -This script will read some limits from the cgroup system and parse -them, printing out "VARIABLE=VALUE" on each line for every limit that is -successfully read. Output of this script can be directly fed into -bash's export command. Recommended usage from a bash script: - - set -o errexit - export_vars=$(cgroup-limits) ; export $export_vars - -Variables currently supported: - MAX_MEMORY_LIMIT_IN_BYTES - Maximum possible limit MEMORY_LIMIT_IN_BYTES can have. This is - currently constant value of 9223372036854775807. - MEMORY_LIMIT_IN_BYTES - Maximum amount of user memory in bytes. If this value is set - to the same value as MAX_MEMORY_LIMIT_IN_BYTES, it means that - there is no limit set. The value is taken from - /sys/fs/cgroup/memory/memory.limit_in_bytes - NUMBER_OF_CORES - Number of detected CPU cores that can be used. This value is - calculated from /sys/fs/cgroup/cpuset/cpuset.cpus - NO_MEMORY_LIMIT - Set to "true" if MEMORY_LIMIT_IN_BYTES is so high that the caller - can act as if no memory limit was set. Undefined otherwise. -""" - -from __future__ import print_function -import sys - - -def _read_file(path): - try: - with open(path, 'r') as f: - return f.read().strip() - except IOError: - return None - - -def get_memory_limit(): - """ - Read memory limit, in bytes. - """ - - limit = _read_file('/sys/fs/cgroup/memory/memory.limit_in_bytes') - if limit is None or not limit.isdigit(): - print("Warning: Can't detect memory limit from cgroups", - file=sys.stderr) - return None - return int(limit) - - -def get_number_of_cores(): - """ - Read number of CPU cores. - """ - - core_count = 0 - - line = _read_file('/sys/fs/cgroup/cpuset/cpuset.cpus') - if line is None: - print("Warning: Can't detect number of CPU cores from cgroups", - file=sys.stderr) - return None - - for group in line.split(','): - core_ids = list(map(int, group.split('-'))) - if len(core_ids) == 2: - core_count += core_ids[1] - core_ids[0] + 1 - else: - core_count += 1 - - return core_count - - -if __name__ == "__main__": - env_vars = { - "MAX_MEMORY_LIMIT_IN_BYTES": 9223372036854775807, - "MEMORY_LIMIT_IN_BYTES": get_memory_limit(), - "NUMBER_OF_CORES": get_number_of_cores() - } - - env_vars = {k: v for k, v in env_vars.items() if v is not None} - - if env_vars.get("MEMORY_LIMIT_IN_BYTES", 0) >= 92233720368547: - env_vars["NO_MEMORY_LIMIT"] = "true" - - for key, value in env_vars.items(): - print("{0}={1}".format(key, value)) \ No newline at end of file diff --git a/bin/fix-permissions b/bin/fix-permissions deleted file mode 100755 index b6ab3fd..0000000 --- a/bin/fix-permissions +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -# Allow this script to fail without failing a build -set +e - -# Fix permissions on the given directory to allow group read/write of -# regular files and execute of directories. -chgrp -R 0 $1; -find -L $1 -xtype l -exec chgrp 0 {} \; -chmod -R g+rw $1; -find -L $1 -xtype l -exec chmod g+rw {} \; -find $1 -type d -exec chmod g+x {} + \ No newline at end of file diff --git a/contrib/etc/httpd.conf b/contrib/etc/httpd.conf deleted file mode 100644 index 66dc0fb..0000000 --- a/contrib/etc/httpd.conf +++ /dev/null @@ -1,18 +0,0 @@ - -LoadModule perl_module modules/mod_perl.so -DirectoryIndex index.pl - -PerlSwitches -I./extlib/lib/perl5 - - - SetHandler perl-script - PerlResponseHandler ModPerl::PerlRun - Options +ExecCGI +SymLinksIfOwnerMatch - PerlSendHeader On - - - - Require all granted - - -IncludeOptional /opt/app-root/etc/httpd.d/*.conf \ No newline at end of file diff --git a/contrib/etc/httpd.d/50-mpm.conf.template b/contrib/etc/httpd.d/50-mpm.conf.template deleted file mode 100644 index ca18659..0000000 --- a/contrib/etc/httpd.d/50-mpm.conf.template +++ /dev/null @@ -1,11 +0,0 @@ -# This value should mirror what is set in MinSpareServers. -StartServers ${HTTPD_START_SERVERS} -MinSpareServers ${HTTPD_START_SERVERS} -MaxSpareServers ${HTTPD_MAX_SPARE_SERVERS} -# The MaxRequestWorkers directive sets the limit on the number of -# simultaneous requests that will be served. -# The default value, when no cgroup limits are set is 256. -MaxRequestWorkers ${HTTPD_MAX_REQUEST_WORKERS} -ServerLimit ${HTTPD_MAX_REQUEST_WORKERS} -MaxConnectionsPerChild 4000 -MaxKeepAliveRequests 100 diff --git a/contrib/etc/httpdconf.sed b/contrib/etc/httpdconf.sed deleted file mode 100644 index 45f14db..0000000 --- a/contrib/etc/httpdconf.sed +++ /dev/null @@ -1,7 +0,0 @@ -s/^Listen 80/Listen 0.0.0.0:8080/ -s/^User apache/User default/ -s/^Group apache/Group root/ -s%^DocumentRoot "/var/www/html"%DocumentRoot "/opt/app-root/src"% -s%^" "DATE 11.04.2017" "" -.BR perl (1) -\-\- S2I builder of perl applications -.SH USAGE -.PP -To pull the perl container run: -.PP -.RS -.nf - # docker pull koscicz/perl -.fi -.RE -.PP -To build your perl application use run: -.PP -.RS -.nf - # s2i build koscicz/perl -.fi -.RE -.PP -To run your application in docker container: -.PP -.RS -.nf - # docker run \-p 8080:8080 -.fi -.RE -.SH ENVIROMENT VARIABLES -.PP -To set environment variables, you can place them as a key value pair into a \fB\fC\&.sti/environment\fR -file inside your source code repository. -.PP -ENABLE_CPAN_TEST -.PP -.RS -.nf -Allow the installation of all specified cpan packages and the running of their tests. The default value is `false`. -.fi -.RE -.PP -CPAN_MIRROR -.PP -.RS -.nf -This variable specifies a mirror URL which will used by cpanminus to install dependencies. -By default the URL is not specified. -.fi -.RE -.PP -PERL_APACHE2_RELOAD -.PP -.RS -.nf -Set this to "true" to enable automatic reloading of modified Perl modules. -.fi -.RE -.PP -HTTPD_START_SERVERS -.PP -.RS -.nf -The [StartServers](https://httpd.apache.org/docs/2.4/mod/mpm_common.html#startservers) -directive sets the number of child server processes created on startup. Default is 8. -.fi -.RE -.PP -HTTPD_MAX_REQUEST_WORKERS -.PP -.RS -.nf -Number of simultaneous requests that will be handled by Apache. The default -is 256, but it will be automatically lowered if memory is limited. -.fi -.RE -.PP -PSGI_FILE -.PP -.RS -.nf -Override PSGI application detection. - -If the PSGI_FILE variable is set to empty value, no PSGI application will -be detected and mod_perl not be reconfigured. - -If the PSGI_FILE variable is set and non\-empty, it will define path to -the PSGI application file. No detection will be used. - -If the PSGI_FILE variable does not exist, autodetection will be used: -If exactly one ./*.psgi file exists, mod_perl will be configured to -execute that file. -.fi -.RE -.PP -PSGI_URI_PATH -.PP -.RS -.nf -This variable overrides location URI path that is handled path the PSGI -application. Default value is "/". -.fi -.RE diff --git a/root/help.md b/root/help.md deleted file mode 100644 index bfb35d0..0000000 --- a/root/help.md +++ /dev/null @@ -1,63 +0,0 @@ -perl(1) -- S2I builder of perl applications -============================================= - -## USAGE - -To pull the perl container run: - - # docker pull koscicz/perl - -To build your perl application use run: - - # s2i build koscicz/perl - -To run your application in docker container: - - # docker run -p 8080:8080 - -## ENVIROMENT VARIABLES - -To set environment variables, you can place them as a key value pair into a `.sti/environment` -file inside your source code repository. - -ENABLE\_CPAN\_TEST - - Allow the installation of all specified cpan packages and the running of their tests. The default value is `false`. - -CPAN_MIRROR - - This variable specifies a mirror URL which will used by cpanminus to install dependencies. - By default the URL is not specified. - -PERL\_APACHE2\_RELOAD - - Set this to "true" to enable automatic reloading of modified Perl modules. - -HTTPD\_START\_SERVERS - - The [StartServers](https://httpd.apache.org/docs/2.4/mod/mpm_common.html#startservers) - directive sets the number of child server processes created on startup. Default is 8. - -HTTPD\_MAX\_REQUEST\_WORKERS - - Number of simultaneous requests that will be handled by Apache. The default - is 256, but it will be automatically lowered if memory is limited. - -PSGI_FILE - - Override PSGI application detection. - - If the PSGI_FILE variable is set to empty value, no PSGI application will - be detected and mod_perl not be reconfigured. - - If the PSGI_FILE variable is set and non-empty, it will define path to - the PSGI application file. No detection will be used. - - If the PSGI_FILE variable does not exist, autodetection will be used: - If exactly one ./*.psgi file exists, mod_perl will be configured to - execute that file. - -PSGI\_URI\_PATH - - This variable overrides location URI path that is handled path the PSGI - application. Default value is "/". \ No newline at end of file diff --git a/s2i/bin/assemble b/s2i/bin/assemble deleted file mode 100755 index 2363d37..0000000 --- a/s2i/bin/assemble +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/bash - -set -e - -shopt -s dotglob -echo "---> Installing application source ..." -mv /tmp/src/* ./ - -if [ -d ./cfg ]; then - echo "---> Copying configuration files..." - if [ "$(ls -A ./cfg/*.conf)" ]; then - cp -v ./cfg/*.conf /opt/app-root/etc/httpd.d/ - fi -fi - -# Allow for http proxy to be specified in uppercase -if [[ -n "${HTTP_PROXY:-}" && -z "${http_proxy:-}" ]]; then - export http_proxy=$HTTP_PROXY -fi - -export CPAN_MIRROR=${CPAN_MIRROR:-""} - -MIRROR_ARGS="" - -if [ -n "$CPAN_MIRROR" ]; then - MIRROR_ARGS="--mirror $CPAN_MIRROR" -fi - -# Don't test installed Perl modules by default -if [ "${ENABLE_CPAN_TEST}" = true ]; then - export ENABLE_CPAN_TEST="" -else - export ENABLE_CPAN_TEST="--notest" -fi - -# Configure mod_perl for PSGI. -# If PSGI_FILE variable is set but empty, skip it. -# If PSGI_FILE is set and non-empty, use it. -# If PSGI_FILE does not exist, check if exactly one ./*.psgi file exists and -# use that file. -# If PSGI_URI_PATH variable has a value, use it as a location. Default is "/". -if [ ! -v PSGI_FILE ]; then - PSGI_FILE=$(find -maxdepth 1 -name '*.psgi' -type f) -fi -PSGI_FILE_NUMBER=$(printf '%s' "$PSGI_FILE" | wc -l) -if [ -n "$PSGI_FILE" -a "$PSGI_FILE_NUMBER" -eq 0 ]; then - echo "---> PSGI application found in $PSGI_FILE" - cat >> cpanfile <<"EOF" -requires 'Plack::Handler::Apache2'; -EOF - # XXX: Escape PSGI_FILE value against httpd control characters - PSGI_FILE=$(printf '%s' "$PSGI_FILE" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g') - cat > /opt/app-root/etc/httpd.d/40-psgi.conf < - SetHandler perl-script - PerlResponseHandler Plack::Handler::Apache2 - PerlSetVar psgi_app "$PSGI_FILE" - -EOF -elif [ "$PSGI_FILE_NUMBER" -gt 0 ]; then - echo "---> Multiple PSGI applications found:" - printf '%s' "$PSGI_FILE" - echo "---> Skipping PSGI autoconfiguration!" -fi - -# Installing dependencies with cpanfile -if [ -f "cpanfile" ]; then - echo "---> Installing modules from cpanfile ..." - cpanm $MIRROR_ARGS $ENABLE_CPAN_TEST -l extlib Module::CoreList - cpanm $MIRROR_ARGS $ENABLE_CPAN_TEST -l extlib --installdeps . -else - echo "---> No cpanfile found, nothing to install" -fi - -# Fix source directory permissions -fix-permissions ./ \ No newline at end of file diff --git a/s2i/bin/run b/s2i/bin/run deleted file mode 100755 index 687feb1..0000000 --- a/s2i/bin/run +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash - -set -e - -# CPAN can install scripts. They should be available from mod_perl too. -export PATH=${PATH}:/opt/app-root/src/extlib/bin -# And we have to set Perl include path too because mod_perl's PerlSwitches -# does not apply to them. -export PERL5LIB=/opt/app-root/src/extlib/lib/perl5 - -# Warning: Please note that this will pass all environment variables available within the -# container to mod_perl by means of PerlPassEnv in the env.conf file -if [ ! -f /opt/app-root/etc/httpd.d/env.conf ]; then - env | awk -F'=' '{print "PerlPassEnv "$1}' > /opt/app-root/etc/httpd.d/env.conf -fi - -# Enable automatic reloading. This can be useful for debugging an application. -PERL_APACHE2_RELOAD=${PERL_APACHE2_RELOAD:-} -if [[ "${PERL_APACHE2_RELOAD,,}" == "true" ]]; then - cat > /opt/app-root/etc/httpd.d/50-autoreload.conf < 0 ? MAX_SERVER_LIMIT : 1)) - export HTTPD_MAX_REQUEST_WORKERS=$((MAX_SERVER_LIMIT > 256 ? 256 : MAX_SERVER_LIMIT)) -fi - -export HTTPD_START_SERVERS=${HTTPD_START_SERVERS:-8} -export HTTPD_MAX_SPARE_SERVERS=$((HTTPD_START_SERVERS+10)) - -envsubst < /opt/app-root/etc/httpd.d/50-mpm.conf.template > /opt/app-root/etc/httpd.d/50-mpm.conf - -exec httpd -C 'Include /opt/app-root/etc/httpd.conf' -D FOREGROUND \ No newline at end of file diff --git a/s2i/bin/usage b/s2i/bin/usage deleted file mode 100755 index ddfa51b..0000000 --- a/s2i/bin/usage +++ /dev/null @@ -1,11 +0,0 @@ - -#!/bin/sh - -cat <