From a8f4df04796fa3ade425a739ecb4fb9dc22c4a21 Mon Sep 17 00:00:00 2001 From: Corey Daley Date: Mon, 6 Feb 2017 15:58:16 -0500 Subject: [PATCH] Overhaul of Source-to-Image Updating README(s), templates, and examples --- README.md | 4 +- cmd/s2i/main.go | 1 + docs/cli.md | 18 +- examples/README.md | 52 ------ examples/nginx-app/save-artifacts | 16 -- examples/nginx-app/test/index.html | 13 -- .../{nginx-app => nginx-centos7}/Dockerfile | 33 ++-- examples/nginx-centos7/Makefile | 11 ++ examples/nginx-centos7/README.md | 82 +++++++++ .../s2i/bin}/assemble | 17 +- .../{nginx-app => nginx-centos7/s2i/bin}/run | 2 +- examples/nginx-centos7/s2i/bin/save-artifacts | 10 ++ .../s2i/bin}/usage | 4 +- examples/nginx-centos7/test/run | 160 ++++++++++++++++++ .../nginx-centos7/test/test-app/index.html | 10 ++ hack/test-stirunimage.sh | 4 +- pkg/create/create.go | 17 +- pkg/create/templates/docker.go | 7 +- pkg/create/templates/readme.go | 91 ++++++++++ pkg/create/templates/scripts.go | 7 +- pkg/create/templates/test.go | 16 +- test/integration/integration_test.go | 4 +- 22 files changed, 448 insertions(+), 131 deletions(-) delete mode 100644 examples/README.md delete mode 100755 examples/nginx-app/save-artifacts delete mode 100644 examples/nginx-app/test/index.html rename examples/{nginx-app => nginx-centos7}/Dockerfile (51%) create mode 100644 examples/nginx-centos7/Makefile create mode 100755 examples/nginx-centos7/README.md rename examples/{nginx-app => nginx-centos7/s2i/bin}/assemble (72%) rename examples/{nginx-app => nginx-centos7/s2i/bin}/run (84%) create mode 100755 examples/nginx-centos7/s2i/bin/save-artifacts rename examples/{nginx-app => nginx-centos7/s2i/bin}/usage (70%) create mode 100755 examples/nginx-centos7/test/run create mode 100755 examples/nginx-centos7/test/test-app/index.html create mode 100644 pkg/create/templates/readme.go diff --git a/README.md b/README.md index d63027dad..c141465f5 100644 --- a/README.md +++ b/README.md @@ -233,12 +233,12 @@ You can start using `s2i` right away (see [releases](https://github.com/openshif with the following test sources and publicly available images: ``` -$ s2i build https://github.com/pmorie/simple-ruby openshift/ruby-20-centos7 test-ruby-app +$ s2i build https://github.com/openshift/ruby-hello-world openshift/ruby-23-centos7 test-ruby-app $ docker run --rm -i -p :8080 -t test-ruby-app ``` ``` -$ s2i build https://github.com/bparees/openshift-jee-sample openshift/wildfly-100-centos7 test-jee-app +$ s2i build --ref=7.1.x --context-dir=helloworld https://github.com/jboss-developer/jboss-eap-quickstarts openshift/wildfly-101-centos7 test-jee-app $ docker run --rm -i -p :8080 -t test-jee-app ``` diff --git a/cmd/s2i/main.go b/cmd/s2i/main.go index 78980bf72..e8f75ba0f 100644 --- a/cmd/s2i/main.go +++ b/cmd/s2i/main.go @@ -269,6 +269,7 @@ func newCmdCreate() *cobra.Command { b := create.New(args[0], args[1]) b.AddSTIScripts() b.AddDockerfile() + b.AddReadme() b.AddTests() }, } diff --git a/docs/cli.md b/docs/cli.md index b748d8eb9..9f64a0f6c 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -146,11 +146,11 @@ Example: data posted will be in the form: #### Example Usage -Build a Ruby application from a Git source, using the official `ruby-20-centos7` builder +Build a Ruby application from a Git source, using the official `ruby-23-centos7` builder image, the resulting image will be named `ruby-app`: ``` -$ s2i build https://github.com/mfojtik/sinatra-app-example openshift/ruby-20-centos7 ruby-app +$ s2i build https://github.com/openshift/ruby-hello-world openshift/ruby-23-centos7 ruby-app ``` Build a Node.js application from a local directory, using a local image, the resulting @@ -167,19 +167,19 @@ Use this method only for development or local testing. **NOTE**: All your changes have to be committed by `git` in order to build them with S2I. -Build a Java application from a Git source, using the official `openshift/wildfly-100-centos7` +Build a Java application from a Git source, using the official `openshift/wildfly-101-centos7` builder image but overriding the scripts URL from local directory. The resulting image will be named `java-app`: ``` -$ s2i build --scripts-url=file://s2iscripts https://github.com/bparees/openshift-jee-sample openshift/wildfly-100-centos7 java-app +$ s2i build --scripts-url=file://s2iscripts --ref=7.1.x --context-dir=kitchensink https://github.com/jboss-developer/jboss-eap-quickstarts openshift/wildfly-101-centos7 java-app ``` Build a Ruby application from a Git source, specifying `ref`, and using the official -`ruby-20-centos7` builder image. The resulting image will be named `ruby-app`: +`ruby-23-centos7` builder image. The resulting image will be named `ruby-app`: ``` -$ s2i build --ref=my-branch https://github.com/mfojtik/sinatra-app-example openshift/ruby-20-centos7 ruby-app +$ s2i build --ref=my-branch https://github.com/openshift/ruby-hello-world openshift/ruby-23-centos7 ruby-app ``` ***NOTE:*** If the ref is invalid or not present in the source repository then the build will fail. @@ -188,7 +188,7 @@ Build a Ruby application from a Git source, overriding the scripts URL from a lo and specifying the scripts and sources be placed in `/opt` directory: ``` -$ s2i build --scripts-url=file://s2iscripts --destination=/opt https://github.com/mfojtik/sinatra-app-example openshift/ruby-20-centos7 ruby-app +$ s2i build --scripts-url=file://s2iscripts --destination=/opt https://github.com/openshift/ruby-hello-world openshift/ruby-23-centos7 ruby-app ``` # s2i rebuild @@ -232,9 +232,9 @@ $ s2i usage [flags] #### Example Usage -Print the official `ruby-20-centos7` builder image usage: +Print the official `ruby-23-centos7` builder image usage: ``` -$ s2i usage openshift/ruby-20-centos7 +$ s2i usage openshift/ruby-23-centos7 ``` diff --git a/examples/README.md b/examples/README.md deleted file mode 100644 index 941fe7d09..000000000 --- a/examples/README.md +++ /dev/null @@ -1,52 +0,0 @@ -Creating a basic S2I builder image ---- - -### Getting started - -Directory skeleton: - -* `Dockerfile` – standard Dockerfile where we’ll define the base builder image. -* `assemble` - responsible for building the application. -* `run` - responsible for running the application. -* `save-artifacts` - optional script for incremental builds that save built artifacts. -* `usage` - optional script responsible for printing the usage of the builder. - -The first step is to create a `Dockerfile` that installs all the necessary tools and libraries that are needed to build and run our application. -You can find an example of the Dockerfile [`here`](nginx-app/Dockerfile). - -The next step is to create an `assemble` script that will, for example, build python modules, bundle install our required components or setup application specific configuration based on the logic we define in it. We can specify a way to restore any saved artifacts from the previous image. In [`this`](nginx-app/assemble) example it will only copy our index.html over the default one. - -Now we can create our `run` script that will start the application. You can see an example [`here`](nginx-app/run). - -Optionally we can also specify a `save-artifacts` script, which allows a new build to reuses content from a previous version of the application image. -An example can be found [`here`](nginx-app/save-artifacts). - -We can provide some help to the user on how to use it as a base for an application image via the `usage` script. An example can be found [`here`](nginx-app/usage). - -Make sure all the scripts are runnable `chmod +x assemble run save-artifacts usage` - -The next step is to create the builder image. In the nginx-app directory issue `docker build -t nginx-centos7 .` -This will create a builder image from the current Dockerfile. - -Once the builder image is done, the user can issue `s2i usage nginx-centos7` which will print out the help info that was defined in our `usage` script. - -The next step is to create `the application image`. We will create this with the content from the source directory `test` from this repo. In this source directory we have only one file for this example, `index.html`. - -``` -s2i build test/ nginx-centos7 nginx-app ----> Building and installing application from source... -``` -All the logic defined previously in the `assemble` script will now be executed thus compiling your assets or setting up application specific configuration. - -Running the application image is as simple as invoking the docker run command: -`docker run -d -p 8080:8080 nginx-app` - -Now you should be able to access a static web page served by our newly created application image on [http://localhost:8080](http://localhost:8080). - -If we want to rebuild the application with the saved artifacts, then we can do: -``` -s2i build --incremental=true test/ nginx-centos7 nginx-app ----> Restoring build artifacts... ----> Building and installing application from source... -``` -This will run the `save-artifacts` script that has the code which will save your artifacts from the previously built application image, and then inject those artifacts into the new image according to the logic you specified in the `assemble` script. diff --git a/examples/nginx-app/save-artifacts b/examples/nginx-app/save-artifacts deleted file mode 100755 index 96597aa73..000000000 --- a/examples/nginx-app/save-artifacts +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -e -# -# S2I save-artifacts script for the 'nginx-centos7' image. -# The save-artifacts script streams a tar archive to standard output. -# The archive contains the files and folders you want to re-use in the next build. -# -# For more information see the documentation: -# https://github.com/openshift/source-to-image/blob/master/docs/builder_image.md -# -# Replace this with any logic that you need in order to save all of your built artifacts from -# your application so they can be reused in a future build to save time. -touch /tmp/artifact -cd /tmp -# the final step of the assemble script is to stream a tar of the artifacts to be saved, to stdout. -# This tar stream will be received by s2i and used as an input to the build -tar cf - artifact diff --git a/examples/nginx-app/test/index.html b/examples/nginx-app/test/index.html deleted file mode 100644 index 364890a90..000000000 --- a/examples/nginx-app/test/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - openshift/source-to-image tutorial - - - - -

Hello World

- - diff --git a/examples/nginx-app/Dockerfile b/examples/nginx-centos7/Dockerfile similarity index 51% rename from examples/nginx-app/Dockerfile rename to examples/nginx-centos7/Dockerfile index e9f21fa83..10675e1ed 100644 --- a/examples/nginx-app/Dockerfile +++ b/examples/nginx-centos7/Dockerfile @@ -1,12 +1,13 @@ + # nginx-centos7 -# Here you can use whatever image base is relevant for your application. +# Here you can use whatever base image is relevant for your application. FROM centos:centos7 # Here you can specify the maintainer for the image that you're building -MAINTAINER Victor Palade +MAINTAINER Your Name -# Export the environment variable that provides information about the application. -# Replace this with the according version for your application. +# Export an environment variable that provides information about the application version. +# Replace this with the version for your application. ENV NGINX_VERSION=1.6.3 # Set the labels that are used for OpenShift to describe the builder image. @@ -18,18 +19,30 @@ LABEL io.k8s.description="Nginx Webserver" \ # (run, assemble, save-artifacts) io.openshift.s2i.scripts-url="image:///usr/libexec/s2i" -# Install our Nginx package and clean the yum cache so that we don't have any -# cached files waste space. -RUN yum install -y epel-release && \ +# Install the nginx web server package and clean the yum cache +RUN yum install -y epel-release && \ yum install -y --setopt=tsflags=nodocs nginx && \ yum clean all -# We will change the default port for nginx (It's required if you plan on -# running images as non-root user). +# Change the default port for nginx +# Required if you plan on running images as a non-root user). RUN sed -i 's/80/8080/' /etc/nginx/nginx.conf +RUN sed -i 's/user nginx;//' /etc/nginx/nginx.conf # Copy the S2I scripts to /usr/libexec/s2i since we set the label that way -COPY ["run", "assemble", "save-artifacts", "usage", "/usr/libexec/s2i/"] +COPY ./s2i/bin/ /usr/libexec/s2i + +RUN chown -R 1001:1001 /opt/app-root +RUN chown -R 1001:1001 /usr/share/nginx +RUN chown -R 1001:1001 /var/log/nginx +RUN chown -R 1001:1001 /var/lib/nginx +RUN touch /run/nginx.pid +RUN chown -R 1001:1001 /run/nginx.pid + +USER 1001 + +# Set the default port for applications built using this image +EXPOSE 8080 # Modify the usage script in your application dir to inform the user how to run # this image. diff --git a/examples/nginx-centos7/Makefile b/examples/nginx-centos7/Makefile new file mode 100644 index 000000000..6a757d118 --- /dev/null +++ b/examples/nginx-centos7/Makefile @@ -0,0 +1,11 @@ + +IMAGE_NAME = nginx-centos7 + +.PHONY: build +build: + docker build -t $(IMAGE_NAME) . + +.PHONY: test +test: + docker build -t $(IMAGE_NAME)-candidate . + IMAGE_NAME=$(IMAGE_NAME)-candidate test/run diff --git a/examples/nginx-centos7/README.md b/examples/nginx-centos7/README.md new file mode 100755 index 000000000..3387fbd55 --- /dev/null +++ b/examples/nginx-centos7/README.md @@ -0,0 +1,82 @@ + +# Creating a basic S2I builder image + +## Getting started + +### Files and Directories +| File | Required? | Description | +|------------------------|-----------|--------------------------------------------------------------| +| Dockerfile | Yes | Defines the base builder image | +| s2i/bin/assemble | Yes | Script that builds the application | +| s2i/bin/usage | No | Script that prints the usage of the builder | +| s2i/bin/run | Yes | Script that runs the application | +| s2i/bin/save-artifacts | No | Script for incremental builds that saves the built artifacts | +| test/run | No | Test script for the builder image | +| test/test-app | Yes | Test application source code | + +#### Dockerfile +Create a *Dockerfile* that installs all of the necessary tools and libraries that are needed to build and run our application. This file will also handle copying the s2i scripts into the created image. + +#### S2I scripts + +##### assemble +Create an *assemble* script that will build our application, e.g.: +- build python modules +- bundle install ruby gems +- setup application specific configuration + +The script can also specify a way to restore any saved artifacts from the previous image. + +##### run +Create a *run* script that will start the application. + +##### save-artifacts (optional) +Create a *save-artifacts* script which allows a new build to reuse content from a previous version of the application image. + +##### usage (optional) +Create a *usage* script that will print out instructions on how to use the image. + +##### Make the scripts executable +Make sure that all of the scripts are executable by running *chmod +x s2i/bin/** + +#### Create the builder image +The following command will create a builder image named nginx-centos7 based on the Dockerfile that was created previously. +``` +docker build -t nginx-centos7 . +``` +The builder image can also be created by using the *make* command since a *Makefile* is included. + +Once image has finished building, the command *s2i usage nginx-centos7* will print out the help info that was defined in the *usage* script. + +#### Testing the builder image +The builder image can be tested using the following commands: +``` +docker build -t nginx-centos7-candidate . +IMAGE_NAME=nginx-centos7-candidate test/run +``` +The builder image can also be tested by using the *make test* command since a *Makefile* is included. + +#### Creating the application image +The application image combines the builder image with your applications source code, which is served using whatever application is installed via the *Dockerfile*, compiled using the *assemble* script, and run using the *run* script. +The following command will create the application image: +``` +s2i build test/test-app nginx-centos7 nginx-centos7-app +---> Building and installing application from source... +``` +Using the logic defined in the *assemble* script, s2i will now create an application image using the builder image as a base and including the source code from the test/test-app directory. + +#### Running the application image +Running the application image is as simple as invoking the docker run command: +``` +docker run -d -p 8080:8080 nginx-centos7-app +``` +The application, which consists of a simple static web page, should now be accessible at [http://localhost:8080](http://localhost:8080). + +#### Using the saved artifacts script +Rebuilding the application using the saved artifacts can be accomplished using the following command: +``` +s2i build --incremental=true test/test-app nginx-centos7 nginx-app +---> Restoring build artifacts... +---> Building and installing application from source... +``` +This will run the *save-artifacts* script which includes the custom code to backup the currently running application source, rebuild the application image, and then re-deploy the previously saved source using the *assemble* script. diff --git a/examples/nginx-app/assemble b/examples/nginx-centos7/s2i/bin/assemble similarity index 72% rename from examples/nginx-app/assemble rename to examples/nginx-centos7/s2i/bin/assemble index 9465373e8..47350abd6 100755 --- a/examples/nginx-app/assemble +++ b/examples/nginx-centos7/s2i/bin/assemble @@ -16,13 +16,16 @@ fi # Restore artifacts from the previous build (if they exist). # We set them here just for show, but you will need to set this up with your logic # according to the application directory that you chose. -if [ "$(ls /tmp/artifacts/ 2>/dev/null)" ]; then - echo "---> Restoring build artifacts..." - mv /tmp/artifacts/* /usr/share/nginx/html/ -fi -# Override our default nginx index.html file. -# This is what we consider in this example `installing the application` + +#if [ "$(ls /tmp/artifacts/ 2>/dev/null)" ]; then +# echo "---> Restoring build artifacts..." +# mv /tmp/artifacts/* +#fi + +# Override the default nginx index.html file. +# This is what we consider in this example 'installing the application' # here you can go ahead an replace this with the actual building of python modules, # bundle install, and anything else you need. + echo "---> Building and installing application from source..." -cp -Rf /tmp/src/index.html /usr/share/nginx/html/index.html +mv /tmp/src/* /usr/share/nginx/html/ diff --git a/examples/nginx-app/run b/examples/nginx-centos7/s2i/bin/run similarity index 84% rename from examples/nginx-app/run rename to examples/nginx-centos7/s2i/bin/run index 7d2589cea..96fb1b47a 100755 --- a/examples/nginx-app/run +++ b/examples/nginx-centos7/s2i/bin/run @@ -7,5 +7,5 @@ # We will turn off daemonizing for the nginx process so that the container # doesn't exit after the process runs. -# We will also specify the default port on which it should listen. + exec /usr/sbin/nginx -g "daemon off;" diff --git a/examples/nginx-centos7/s2i/bin/save-artifacts b/examples/nginx-centos7/s2i/bin/save-artifacts new file mode 100755 index 000000000..78316e837 --- /dev/null +++ b/examples/nginx-centos7/s2i/bin/save-artifacts @@ -0,0 +1,10 @@ +#!/bin/sh -e +# +# S2I save-artifacts script for the 'nginx-centos7' image. +# The save-artifacts script streams a tar archive to standard output. +# The archive contains the files and folders you want to re-use in the next build. +# +# For more information see the documentation: +# https://github.com/openshift/source-to-image/blob/master/docs/builder_image.md +# +#tar cf - diff --git a/examples/nginx-app/usage b/examples/nginx-centos7/s2i/bin/usage similarity index 70% rename from examples/nginx-app/usage rename to examples/nginx-centos7/s2i/bin/usage index c32167a91..65ea46072 100755 --- a/examples/nginx-app/usage +++ b/examples/nginx-centos7/s2i/bin/usage @@ -5,9 +5,9 @@ To use it, install S2I: https://github.com/openshift/source-to-image Sample invocation: -s2i build test/ nginx-centos7 nginx-app +s2i build test/test-app nginx-centos7 nginx-centos7-app You can then run the resulting image via: -docker run -d -p 8080:8080 nginx-app +docker run -d -p 8080:8080 nginx-centos7-app and see the test via http://localhost:8080 EOF diff --git a/examples/nginx-centos7/test/run b/examples/nginx-centos7/test/run new file mode 100755 index 000000000..e84d83c70 --- /dev/null +++ b/examples/nginx-centos7/test/run @@ -0,0 +1,160 @@ +#!/bin/bash +# +# The 'run' performs a simple test that verifies the S2I image. +# The main focus here is to exercise the S2I scripts. +# +# For more information see the documentation: +# https://github.com/openshift/source-to-image/blob/master/docs/builder_image.md +# +# IMAGE_NAME specifies a name of the candidate image used for testing. +# The image has to be available before this script is executed. +# +IMAGE_NAME=${IMAGE_NAME-nginx-centos7-candidate} + +# Determining system utility executables (darwin compatibility check) +READLINK_EXEC="readlink" +MKTEMP_EXEC="mktemp" +if [[ "$OSTYPE" =~ 'darwin' ]]; then + ! type -a "greadlink" &>"/dev/null" || READLINK_EXEC="greadlink" + ! type -a "gmktemp" &>"/dev/null" || MKTEMP_EXEC="gmktemp" +fi + +test_dir="$($READLINK_EXEC -zf $(dirname "${BASH_SOURCE[0]}"))" +image_dir=$($READLINK_EXEC -zf ${test_dir}/..) +scripts_url="file://${image_dir}/.s2i/bin" +cid_file=$($MKTEMP_EXEC -u --suffix=.cid) + +# Since we built the candidate image locally, we don't want S2I to attempt to pull +# it from Docker hub +s2i_args="--pull-policy=never --loglevel=2" + +# Port the image exposes service to be tested +test_port=8080 + +image_exists() { + docker inspect $1 &>/dev/null +} + +container_exists() { + image_exists $(cat $cid_file) +} + +container_ip() { + if [ ! -z "$DOCKER_HOST" ] && [[ "$OSTYPE" =~ 'darwin' ]]; then + docker-machine ip + else + docker inspect --format="{{ .NetworkSettings.IPAddress }}" $(cat $cid_file) + fi +} + +container_port() { + if [ ! -z "$DOCKER_HOST" ] && [[ "$OSTYPE" =~ 'darwin' ]]; then + docker inspect --format="{{(index .NetworkSettings.Ports \"$test_port/tcp\" 0).HostPort}}" "$(cat "${cid_file}")" + else + echo $test_port + fi +} + +run_s2i_build() { + s2i build --incremental=true ${s2i_args} file://${test_dir}/test-app ${IMAGE_NAME} ${IMAGE_NAME}-testapp +} + +prepare() { + if ! image_exists ${IMAGE_NAME}; then + echo "ERROR: The image ${IMAGE_NAME} must exist before this script is executed." + exit 1 + fi + # s2i build requires the application is a valid 'Git' repository + pushd ${test_dir}/test-app >/dev/null + git init + git config user.email "build@localhost" && git config user.name "builder" + git add -A && git commit -m "Sample commit" + popd >/dev/null + run_s2i_build +} + +run_test_application() { + docker run --rm --cidfile=${cid_file} -p ${test_port} ${IMAGE_NAME}-testapp +} + +cleanup() { + if [ -f $cid_file ]; then + if container_exists; then + docker stop $(cat $cid_file) + fi + fi + if image_exists ${IMAGE_NAME}-testapp; then + docker rmi ${IMAGE_NAME}-testapp + fi +} + +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=10 + local sleep_time=1 + local attempt=1 + local result=1 + while [ $attempt -le $max_attempts ]; do + [ -f $cid_file ] && break + echo "Waiting for container to start..." + attempt=$(( $attempt + 1 )) + sleep $sleep_time + done +} + +test_usage() { + echo "Testing 's2i usage'..." + s2i usage ${s2i_args} ${IMAGE_NAME} &>/dev/null +} + +test_connection() { + echo "Testing HTTP connection (http://$(container_ip):$(container_port))" + 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):$(container_port)/" + response_code=$(curl -s -w %{http_code} -o /dev/null http://$(container_ip):$(container_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 +} + +# Build the application image twice to ensure the 'save-artifacts' and +# 'restore-artifacts' scripts are working properly +prepare +run_s2i_build +check_result $? + +# Verify the 'usage' script is working properly +test_usage +check_result $? + +# Verify that the HTTP connection can be established to test application container +run_test_application & + +# Wait for the container to write its CID file +wait_for_cid + +test_connection +check_result $? + +cleanup + diff --git a/examples/nginx-centos7/test/test-app/index.html b/examples/nginx-centos7/test/test-app/index.html new file mode 100755 index 000000000..ed3f0b26b --- /dev/null +++ b/examples/nginx-centos7/test/test-app/index.html @@ -0,0 +1,10 @@ + + + + + Hello World! + + +

Hello World!

+ + diff --git a/hack/test-stirunimage.sh b/hack/test-stirunimage.sh index bef71360c..9a22c9404 100755 --- a/hack/test-stirunimage.sh +++ b/hack/test-stirunimage.sh @@ -130,9 +130,9 @@ check_result $? "${WORK_DIR}/s2i-git-proto.log" test_debug "s2i build with --run==true option" if [[ "$OSTYPE" == "cygwin" ]]; then ( cd hack/windows/sigintwrap && make ) - hack/windows/sigintwrap/sigintwrap 's2i build https://github.com/bparees/openshift-jee-sample openshift/wildfly-90-centos7 test-jee-app --run=true --loglevel=5' &> "${WORK_DIR}/s2i-run.log" & + hack/windows/sigintwrap/sigintwrap 's2i build --ref=10.x --context-dir=helloworld https://github.com/wildfly/quickstart openshift/wildfly-101-centos7 test-jee-app --run=true --loglevel=5' &> "${WORK_DIR}/s2i-run.log" & else - s2i build https://github.com/bparees/openshift-jee-sample openshift/wildfly-90-centos7 test-jee-app --run=true --loglevel=5 &> "${WORK_DIR}/s2i-run.log" & + s2i build --ref=10.x --context-dir=helloworld https://github.com/wildfly/quickstart openshift/wildfly-101-centos7 test-jee-app --run=true --loglevel=5 &> "${WORK_DIR}/s2i-run.log" & fi S2I_PID=$! TIME_SEC=1000 diff --git a/pkg/create/create.go b/pkg/create/create.go index f9f856f15..84fe29d08 100644 --- a/pkg/create/create.go +++ b/pkg/create/create.go @@ -24,11 +24,11 @@ func New(name, dst string) *Bootstrap { // AddSTIScripts creates the STI scripts directory structure and process // templates for STI scripts func (b *Bootstrap) AddSTIScripts() { - os.MkdirAll(b.DestinationDir+"/"+".s2i/bin", 0700) - b.process(templates.AssembleScript, ".s2i/bin/assemble", 0755) - b.process(templates.RunScript, ".s2i/bin/run", 0755) - b.process(templates.UsageScript, ".s2i/bin/usage", 0755) - b.process(templates.SaveArtifactsScript, ".s2i/bin/save-artifacts", 0755) + os.MkdirAll(b.DestinationDir+"/"+"s2i/bin", 0700) + b.process(templates.AssembleScript, "s2i/bin/assemble", 0755) + b.process(templates.RunScript, "s2i/bin/run", 0755) + b.process(templates.UsageScript, "s2i/bin/usage", 0755) + b.process(templates.SaveArtifactsScript, "s2i/bin/save-artifacts", 0755) } // AddDockerfile creates an example Dockerfile @@ -36,12 +36,17 @@ func (b *Bootstrap) AddDockerfile() { b.process(templates.Dockerfile, "Dockerfile", 0600) } +// AddReadme creates a README.md +func (b *Bootstrap) AddReadme() { + b.process(templates.Readme, "README.md", 0700) +} + // AddTests creates an example test for the STI image and the Makefile func (b *Bootstrap) AddTests() { os.MkdirAll(b.DestinationDir+"/"+"test/test-app", 0700) + b.process(templates.Index, "test/test-app/index.html", 0700) b.process(templates.TestRunScript, "test/run", 0700) b.process(templates.Makefile, "Makefile", 0600) - b.process(templates.Gitignore, "test/.gitignore", 0644) } func (b *Bootstrap) process(t string, dst string, perm os.FileMode) { diff --git a/pkg/create/templates/docker.go b/pkg/create/templates/docker.go index 411e4ec42..26b2a2193 100644 --- a/pkg/create/templates/docker.go +++ b/pkg/create/templates/docker.go @@ -19,12 +19,15 @@ FROM openshift/base-centos7 # TODO: Install required packages here: # RUN yum install -y ... && yum clean all -y +RUN yum install -y rubygems && yum clean all -y +RUN gem install asdf # TODO (optional): Copy the builder files into /opt/app-root # COPY .// /opt/app-root/ -# TODO: Copy the S2I scripts to /usr/libexec/s2i, since openshift/base-centos7 image sets io.openshift.s2i.scripts-url label that way, or update that label -# COPY ./.s2i/bin/ /usr/libexec/s2i +# TODO: Copy the S2I scripts to /usr/libexec/s2i, since openshift/base-centos7 image +# sets io.openshift.s2i.scripts-url label that way, or update that label +COPY ./s2i/bin/ /usr/libexec/s2i # TODO: Drop the root user and make the content of /opt/app-root owned by user 1001 # RUN chown -R 1001:1001 /opt/app-root diff --git a/pkg/create/templates/readme.go b/pkg/create/templates/readme.go new file mode 100644 index 000000000..a6eb19d65 --- /dev/null +++ b/pkg/create/templates/readme.go @@ -0,0 +1,91 @@ +package templates + +// Readme is a default README laid down by s2i create +const Readme = ` +# Creating a basic S2I builder image + +## Getting started + +### Files and Directories +| File | Required? | Description | +|------------------------|-----------|--------------------------------------------------------------| +| Dockerfile | Yes | Defines the base builder image | +| s2i/bin/assemble | Yes | Script that builds the application | +| s2i/bin/usage | No | Script that prints the usage of the builder | +| s2i/bin/run | Yes | Script that runs the application | +| s2i/bin/save-artifacts | No | Script for incremental builds that saves the built artifacts | +| test/run | No | Test script for the builder image | +| test/test-app | Yes | Test application source code | + +#### Dockerfile +Create a *Dockerfile* that installs all of the necessary tools and libraries that are needed to build and run our application. This file will also handle copying the s2i scripts into the created image. + +#### S2I scripts + +##### assemble +Create an *assemble* script that will build our application, e.g.: +- build python modules +- bundle install ruby gems +- setup application specific configuration + +The script can also specify a way to restore any saved artifacts from the previous image. + +##### run +Create a *run* script that will start the application. + +##### save-artifacts (optional) +Create a *save-artifacts* script which allows a new build to reuse content from a previous version of the application image. + +##### usage (optional) +Create a *usage* script that will print out instructions on how to use the image. + +##### Make the scripts executable +Make sure that all of the scripts are executable by running *chmod +x s2i/bin/** + +#### Create the builder image +The following command will create a builder image named {{.ImageName}} based on the Dockerfile that was created previously. +` + + "```\n" + + "docker build -t {{.ImageName}} .\n" + + "```\n" + + `The builder image can also be created by using the *make* command since a *Makefile* is included. + +Once the image has finished building, the command *s2i usage {{.ImageName}}* will print out the help info that was defined in the *usage* script. + +#### Testing the builder image +The builder image can be tested using the following commands: +` + + "```\n" + + "docker build -t {{.ImageName}}-candidate .\n" + + "IMAGE_NAME={{.ImageName}}-candidate test/run\n" + + "```\n" + + `The builder image can also be tested by using the *make test* command since a *Makefile* is included. + +#### Creating the application image +The application image combines the builder image with your applications source code, which is served using whatever application is installed via the *Dockerfile*, compiled using the *assemble* script, and run using the *run* script. +The following command will create the application image: +` + + "```\n" + + "s2i build test/test-app {{.ImageName}} {{.ImageName}}-app\n" + + "---> Building and installing application from source...\n" + + "```\n" + + `Using the logic defined in the *assemble* script, s2i will now create an application image using the builder image as a base and including the source code from the test/test-app directory. + +#### Running the application image +Running the application image is as simple as invoking the docker run command: +` + + "```\n" + + "docker run -d -p 8080:8080 {{.ImageName}}-app\n" + + "```\n" + + `The application, which consists of a simple static web page, should now be accessible at [http://localhost:8080](http://localhost:8080). + +#### Using the saved artifacts script +Rebuilding the application using the saved artifacts can be accomplished using the following command: +` + + "```\n" + + "s2i build --incremental=true test/test-app nginx-centos7 nginx-app\n" + + "---> Restoring build artifacts...\n" + + "---> Building and installing application from source...\n" + + "```\n" + + `This will run the *save-artifacts* script which includes the custom code to backup the currently running application source, rebuild the application image, and then re-deploy the previously saved source using the *assemble* script. +` diff --git a/pkg/create/templates/scripts.go b/pkg/create/templates/scripts.go index 720f53636..11cb9117d 100644 --- a/pkg/create/templates/scripts.go +++ b/pkg/create/templates/scripts.go @@ -10,9 +10,8 @@ const AssembleScript = `#!/bin/bash -e # https://github.com/openshift/source-to-image/blob/master/docs/builder_image.md # +# If the '{{.ImageName}}' assemble script is executed with the '-h' flag, print the usage. if [[ "$1" == "-h" ]]; then - # If the '{{.ImageName}}' assemble script is executed with '-h' flag, - # print the usage. exec /usr/libexec/s2i/usage fi @@ -27,7 +26,7 @@ echo "---> Installing application source..." cp -Rf /tmp/src/. ./ echo "---> Building application from source..." -# TODO: Add build steps for your application, eg npm install, bundle install +# TODO: Add build steps for your application, eg npm install, bundle install, pip install, etc. ` // RunScript is a default run script laid down by s2i create @@ -40,7 +39,7 @@ const RunScript = `#!/bin/bash -e # https://github.com/openshift/source-to-image/blob/master/docs/builder_image.md # -exec +exec asdf -p 8080 ` // UsageScript is a default usage script laid down by s2i create diff --git a/pkg/create/templates/test.go b/pkg/create/templates/test.go index dbbe5db4b..df6678ddc 100644 --- a/pkg/create/templates/test.go +++ b/pkg/create/templates/test.go @@ -167,6 +167,7 @@ cleanup const Makefile = ` IMAGE_NAME = {{.ImageName}} +.PHONY: build build: docker build -t $(IMAGE_NAME) . @@ -176,6 +177,15 @@ test: IMAGE_NAME=$(IMAGE_NAME)-candidate test/run ` -// Gitignore is a sample .gitignore file -const Gitignore = `.git/ -` +// Index contains a sample index.html file. +const Index = ` + + + + Hello World! + + +

Hello World!

+ + + ` diff --git a/test/integration/integration_test.go b/test/integration/integration_test.go index 89dded99f..f2017cc01 100644 --- a/test/integration/integration_test.go +++ b/test/integration/integration_test.go @@ -29,7 +29,7 @@ import ( const ( DefaultDockerSocket = "unix:///var/run/docker.sock" - TestSource = "https://github.com/pmorie/simple-html" + TestSource = "https://github.com/openshift/ruby-hello-world" FakeBuilderImage = "sti_test/sti-fake" FakeUserImage = "sti_test/sti-fake-user" @@ -619,7 +619,7 @@ func (i *integrationTest) runInImage(image string, cmd string) int { func (i *integrationTest) checkBasicBuildState(cID string, workingDir string) { i.fileExists(cID, "/sti-fake/assemble-invoked") i.fileExists(cID, "/sti-fake/run-invoked") - i.fileExists(cID, "/sti-fake/src/index.html") + i.fileExists(cID, "/sti-fake/src/Gemfile") _, err := os.Stat(workingDir) if !os.IsNotExist(err) {