From 7f980f98a741deefe253769b61b623422afe4ac6 Mon Sep 17 00:00:00 2001 From: opensas Date: Thu, 29 Mar 2012 10:02:42 -0300 Subject: [PATCH] initial commit --- .gitignore | 7 + .openshift/action_hooks/build | 5 + .openshift/action_hooks/deploy | 5 + .openshift/action_hooks/load_config | 35 +++++ .openshift/action_hooks/post_deploy | 4 + .openshift/action_hooks/pre_build | 5 + .openshift/action_hooks/start | 22 ++++ .openshift/action_hooks/stop | 65 +++++++++ .openshift/cron/README.cron | 22 ++++ .openshift/cron/daily/.gitignore | 0 .openshift/cron/hourly/.gitignore | 0 .openshift/cron/minutely/.gitignore | 0 .openshift/cron/monthly/.gitignore | 0 .openshift/cron/weekly/README | 16 +++ .openshift/cron/weekly/chrono.dat | 1 + .openshift/cron/weekly/chronograph | 3 + .openshift/cron/weekly/jobs.allow | 12 ++ .openshift/cron/weekly/jobs.deny | 7 + README.md | 196 ++++++++++++++++++++++++++++ conf/openshift.conf | 45 +++++++ 20 files changed, 450 insertions(+) create mode 100644 .gitignore create mode 100755 .openshift/action_hooks/build create mode 100755 .openshift/action_hooks/deploy create mode 100644 .openshift/action_hooks/load_config create mode 100755 .openshift/action_hooks/post_deploy create mode 100755 .openshift/action_hooks/pre_build create mode 100755 .openshift/action_hooks/start create mode 100755 .openshift/action_hooks/stop create mode 100644 .openshift/cron/README.cron create mode 100644 .openshift/cron/daily/.gitignore create mode 100644 .openshift/cron/hourly/.gitignore create mode 100644 .openshift/cron/minutely/.gitignore create mode 100644 .openshift/cron/monthly/.gitignore create mode 100644 .openshift/cron/weekly/README create mode 100644 .openshift/cron/weekly/chrono.dat create mode 100755 .openshift/cron/weekly/chronograph create mode 100644 .openshift/cron/weekly/jobs.allow create mode 100644 .openshift/cron/weekly/jobs.deny create mode 100644 README.md create mode 100644 conf/openshift.conf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bb9c968 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +logs +project/project +project/target +#target #commented for deploying to openshift +tmp +.history +dist \ No newline at end of file diff --git a/.openshift/action_hooks/build b/.openshift/action_hooks/build new file mode 100755 index 0000000..c0df17b --- /dev/null +++ b/.openshift/action_hooks/build @@ -0,0 +1,5 @@ +#!/bin/bash +# This is a simple build script and will be executed on your CI system if +# available. Otherwise it will execute while your application is stopped +# before the deploy step. This script gets executed directly, so it +# could be python, php, ruby, etc. \ No newline at end of file diff --git a/.openshift/action_hooks/deploy b/.openshift/action_hooks/deploy new file mode 100755 index 0000000..ed5eb99 --- /dev/null +++ b/.openshift/action_hooks/deploy @@ -0,0 +1,5 @@ +#!/bin/bash +# This deploy hook gets executed after dependencies are resolved and the +# build hook has been run but before the application has been started back +# up again. This script gets executed directly, so it could be python, php, +# ruby, etc. \ No newline at end of file diff --git a/.openshift/action_hooks/load_config b/.openshift/action_hooks/load_config new file mode 100644 index 0000000..1aff8e2 --- /dev/null +++ b/.openshift/action_hooks/load_config @@ -0,0 +1,35 @@ +#!/bin/bash + +# debug +# set -x + +# check needed vars +if [[ -z $OPENSHIFT_REPO_DIR ]]; then + echo "Error: OPENSHIFT_REPO_DIR not defined" + return 1 +fi + +PLAY_PARAMS="" + +PLAY_CONFIG_FILE="${OPENSHIFT_REPO_DIR}conf/openshift.conf" + +if [[ -f $PLAY_CONFIG_FILE ]]; then + + function read_conf { + local key=$1 + local default=$2 + local result=`grep "^$key[ |=]" $PLAY_CONFIG_FILE` + + # key not found + if [[ -z "$result" ]]; then + echo $default + else + result=`echo "$result" | grep -oP "=.*" | cut -b 1 --complement` + echo $result + fi + } + + PLAY_PARAMS=$(read_conf "openshift.play.params" $PLAY_PARAMS) +fi + +return 0 \ No newline at end of file diff --git a/.openshift/action_hooks/post_deploy b/.openshift/action_hooks/post_deploy new file mode 100755 index 0000000..a57d1f5 --- /dev/null +++ b/.openshift/action_hooks/post_deploy @@ -0,0 +1,4 @@ +#!/bin/bash +# This is a simple post deploy hook executed after your application +# is deployed and started. This script gets executed directly, so +# it could be python, php, ruby, etc. \ No newline at end of file diff --git a/.openshift/action_hooks/pre_build b/.openshift/action_hooks/pre_build new file mode 100755 index 0000000..10cd544 --- /dev/null +++ b/.openshift/action_hooks/pre_build @@ -0,0 +1,5 @@ +#!/bin/bash +# This is a simple script and will be executed on your CI system if +# available. Otherwise it will execute while your application is stopped +# before the build step. This script gets executed directly, so it +# could be python, php, ruby, etc. \ No newline at end of file diff --git a/.openshift/action_hooks/start b/.openshift/action_hooks/start new file mode 100755 index 0000000..e4b16f4 --- /dev/null +++ b/.openshift/action_hooks/start @@ -0,0 +1,22 @@ +#!/bin/bash +# The logic to start up your application should be put in this +# script. The application will work only if it binds to +# $OPENSHIFT_INTERNAL_IP:8080 + + +# loads $PLAY_PARAMS +. ${OPENSHIFT_REPO_DIR}.openshift/action_hooks/load_config + +if [[ ! $? -eq 0 ]]; then + exit $? +fi + +LOG_FILE="${OPENSHIFT_LOG_DIR}play.log" + +APP_COMMAND="${OPENSHIFT_REPO_DIR}target/start $PLAY_PARAMS "\ +"-Dhttp.port=${OPENSHIFT_INTERNAL_PORT} "\ +"-Dhttp.address=${OPENSHIFT_INTERNAL_IP} "\ +"-Dconfig.resource=openshift.conf" + +echo $APP_COMMAND &>> $LOG_FILE +nohup bash -c "$APP_COMMAND &>> ${LOG_FILE} 2>&1" &> /dev/null & \ No newline at end of file diff --git a/.openshift/action_hooks/stop b/.openshift/action_hooks/stop new file mode 100755 index 0000000..f8656f0 --- /dev/null +++ b/.openshift/action_hooks/stop @@ -0,0 +1,65 @@ +#!/bin/bash +# The logic to stop your application should be put in this script. + +# debug +# set -x + +LOG_FILE="${OPENSHIFT_LOG_DIR}play.log" + +function kill_app { + COMMAND="$1" + # try 5 times to kill it + for c in `seq 1 5`; do + echo "Trying to kill proccess, attempt number $c" >> $LOG_FILE + echo "$COMMAND" >> $LOG_FILE + bash -c "$COMMAND &>> $LOG_FILE 2>&1" &> /dev/null + sleep $c + #killed it + if [[ -z `ps -A | grep ' java$'` ]]; then + if [[ -f "RUNNING_PID" ]]; then + rm RUNNING_PID + fi + popd > /dev/null + exit 0 + fi + done +} + +if [[ ! $? -eq 0 ]]; then + exit $? +fi + +pushd "$OPENSHIFT_REPO_DIR" > /dev/null + +#kill play if it was running +if [[ -f "RUNNING_PID" ]]; then + + pid=`cat RUNNING_PID` + echo "Stopping play application" >> $LOG_FILE + + if [[ -n $pid ]]; then + #try to kill it nicely + kill_app "kill -SIGTERM $pid" + #try to kill it harshly + kill_app "kill -SIGKILL $pid" + fi +fi + +#it survived, try to kill java +if [[ -n `ps -A | grep java` ]]; then + echo "Stopping java proccess" >> $LOG_FILE + #try to kill it nicely + kill_app "pkill -SIGTERM java" + #try to kill it harshly + kill_app "pkill -SIGKILL java" +fi + +#couldn't kill it +if [[ -n `ps -A | grep java` ]]; then + echo "Error: could not stop play application, error executing 'pkill java'" >> $LOG_FILE + popd + exit 1 +fi + +popd > /dev/null +exit 0 diff --git a/.openshift/cron/README.cron b/.openshift/cron/README.cron new file mode 100644 index 0000000..aad9138 --- /dev/null +++ b/.openshift/cron/README.cron @@ -0,0 +1,22 @@ +Run scripts or jobs on a periodic basis +======================================= +Any scripts or jobs added to the minutely, hourly, daily, weekly or monthly +directories will be run on a scheduled basis (frequency is as indicated by the +name of the directory) using run-parts. + +run-parts ignores any files that are hidden or dotfiles (.*) or backup +files (*~ or *,) or named *.{rpmsave,rpmorig,rpmnew,swp,cfsaved} + +The presence of two specially named files jobs.deny and jobs.allow controls +how run-parts executes your scripts/jobs. + jobs.deny ===> Prevents specific scripts or jobs from being executed. + jobs.allow ===> Only execute the named scripts or jobs (all other/non-named + scripts that exist in this directory are ignored). + +The principles of jobs.deny and jobs.allow are the same as those of cron.deny +and cron.allow and are described in detail at: + http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/ch-Automating_System_Tasks.html#s2-autotasks-cron-access + +See: man crontab or above link for more details and see the the weekly/ + directory for an example. + diff --git a/.openshift/cron/daily/.gitignore b/.openshift/cron/daily/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/.openshift/cron/hourly/.gitignore b/.openshift/cron/hourly/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/.openshift/cron/minutely/.gitignore b/.openshift/cron/minutely/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/.openshift/cron/monthly/.gitignore b/.openshift/cron/monthly/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/.openshift/cron/weekly/README b/.openshift/cron/weekly/README new file mode 100644 index 0000000..7c3e659 --- /dev/null +++ b/.openshift/cron/weekly/README @@ -0,0 +1,16 @@ +Run scripts or jobs on a weekly basis +===================================== +Any scripts or jobs added to this directory will be run on a scheduled basis +(weekly) using run-parts. + +run-parts ignores any files that are hidden or dotfiles (.*) or backup +files (*~ or *,) or named *.{rpmsave,rpmorig,rpmnew,swp,cfsaved} and handles +the files named jobs.deny and jobs.allow specially. + +In this specific example, the chronograph script is the only script or job file +executed on a weekly basis (due to white-listing it in jobs.allow). And the +README and chrono.dat file are ignored either as a result of being black-listed +in jobs.deny or because they are NOT white-listed in the jobs.allow file. + +For more details, please see ../README.cron file. + diff --git a/.openshift/cron/weekly/chrono.dat b/.openshift/cron/weekly/chrono.dat new file mode 100644 index 0000000..fc4abb8 --- /dev/null +++ b/.openshift/cron/weekly/chrono.dat @@ -0,0 +1 @@ +Time And Relative D...n In Execution (Open)Shift! diff --git a/.openshift/cron/weekly/chronograph b/.openshift/cron/weekly/chronograph new file mode 100755 index 0000000..61de949 --- /dev/null +++ b/.openshift/cron/weekly/chronograph @@ -0,0 +1,3 @@ +#!/bin/bash + +echo "`date`: `cat $(dirname \"$0\")/chrono.dat`" diff --git a/.openshift/cron/weekly/jobs.allow b/.openshift/cron/weekly/jobs.allow new file mode 100644 index 0000000..8d32abc --- /dev/null +++ b/.openshift/cron/weekly/jobs.allow @@ -0,0 +1,12 @@ +# +# Script or job files listed in here (one entry per line) will be +# executed on a weekly-basis. +# +# Example: The chronograph script will be executed weekly but the README +# and chrono.dat files in this directory will be ignored. +# +# The README file is actually ignored due to the entry in the +# jobs.deny which is checked before jobs.allow (this file). +# +chronograph + diff --git a/.openshift/cron/weekly/jobs.deny b/.openshift/cron/weekly/jobs.deny new file mode 100644 index 0000000..73c9450 --- /dev/null +++ b/.openshift/cron/weekly/jobs.deny @@ -0,0 +1,7 @@ +# +# Any script or job files listed in here (one entry per line) will NOT be +# executed (read as ignored by run-parts). +# + +README + diff --git a/README.md b/README.md new file mode 100644 index 0000000..f41784e --- /dev/null +++ b/README.md @@ -0,0 +1,196 @@ +Play framework 2 Scala application on OpenShift Express +============================ + +This git repository will help you get up and running quickly with a Play framework 2 (with Scala) application +on OpenShift Express taking advantage of the do-it-yourself cartridge. + + +Running on OpenShift +-------------------- + +Register at http://openshift.redhat.com/, and then create a diy (do-it-yourself) application: + + rhc app create -a play2scala -t diy-0.1 + +Add this upstream play-example repo: + + cd play2scala + git remote add upstream -m master git://github.com/opensas/play2-scala-openshift-quickstart.git + git pull -s recursive -X theirs upstream master + +Now you should update your appName setting in project/Build.scala to match your application name. + +And use the stage task to prepare your deployment + + play clean compile stage + +Then add your changes to git's index, commit and push the repo upstream: + + git add . + git commit -m "a nice message" + git push origin + +That's it, you can now see your application running at: + + http://play2scala-yournamespace.rhcloud.com + +The first time you do it, it will take quite a few minutes to complete, because git has to upload play's dependencies, but after that git is smart enough to just upload the differences. + +Working with a mysql database +---------------------------- + +Just issue: + + rhc app cartridge add -a play2scala -c mysql-5.1 + +Don't forget to write down the credentials. + +Then uncomment the following lines from your conf/application.conf, like this: + + # openshift mysql database + %openshift.db.url=jdbc:mysql://${OPENSHIFT_DB_HOST}:${OPENSHIFT_DB_PORT}/${OPENSHIFT_APP_NAME} + %openshift.db.driver=com.mysql.jdbc.Driver + %openshift.db.user=admin + %openshift.db.pass= + +You can manage your new MySQL database by embedding phpmyadmin-3.4. + + rhc app cartridge add -a play2scala -c phpmyadmin-3.4 + +It's also a good idea to create a different user with limited privileges on the database. + +Updating your application +------------------------- + +To deploy your changes to openshift just run the stage task, add your changes to the index, commit and push: + +```bash + play clean compile stage + git add . -A + git commit -m "a nice message" + git push origin +``` + +If you want to do a quick test, you can skip the "clean compile" stuff and just run "play stage" + +All right, I know you are lazy, just like me. Si I added a little script to help you with that, just run + +```bash + rhc_deploy "a nice message" +``` + +You may leave the message empty and it will add something like "deployed on Thu Mar 29 04:07:30 ART 2012", you can also pass a "-q" parameter to skip the "clean compile" option. + +Deploying an existing application to openshift +------------------------- + +You can add openshift support to an already existing play application. Let's take the forms application. + +```bash + cd PLAY_INSTALL_FOLDER/samples/scala/forms + + git init + rhc app create -a forms -t diy-0.1 --nogit +``` + +We add the "--nogit" parameter to tell openshift to create the remote repo but don't pull it locally. You'll see something like this: + +```bash + Confirming application 'forms' is available: Success! + + zentasks published: http://forms-opensas.rhcloud.com/ + git url: ssh://uuid@forms-yournamespace.rhcloud.com/~/git/forms.git/ + Disclaimer: This is an experimental cartridge that provides a way to try unsupported languages, frameworks, and middleware on Openshift. +``` +So we will manually add it as a remote repo + + git remote add origin ssh://uuid@forms-yournamespace.rhcloud.com/~/git/forms.git/ + +And the rest is just the same + + git remote add upstream -m master git://github.com/opensas/play2-scala-openshift-quickstart.git + git pull -s recursive -X theirs upstream master + play clean compile stage + +Then add your changes to git's index, commit and push the repo upstream: + + git add . + git commit -m "deploying forms application" + git push origin + + +That's it, you can now see zentasks demo application running at: + + http://zentasks-yournamespace.rhcloud.com + +Trouble shooting +---------------------------- + +To find out what's going on in openshift, issue + + rhc app tail -a play2scala + +If you feel like investigating further, you can + + rhc app show -a play2scala + + Application Info + ================ + play + Framework: raw-0.1 + Creation: 2012-03-18T12:39:18-04:00 + UUID: youruuid + Git URL: ssh://youruuid@play-yournamespace.rhcloud.com/~/git/raw.git/ + Public URL: http://play-yournamespace.rhcloud.com + +Then you can connect using ssh like this: + + ssh youruuid@play-yournamespace.rhcloud.com + + +Configuration +------------- + +When running on openshift, the configuration defined with conf/application.conf will be overriden by conf/openshift.conf, that way you can customize the way your play app will be executed while running on openshift. + +You can also specify additional parameters to pass to play's executable with the **openshift.play.params** key, like this: + + # play framework command configuration + # ~~~~~ + #openshift.play.params=-Xmx512M + + +Having a look under the hood +---------------------------- + +This projects takes advantage of openshift's do-it-yourself cartridge to run play framework 2 application natively. + +Everytime you push changes to openshift, the following actions will take place: + +* Openshift will run the **.openshift/action_hooks/stop** script to stop the application, in case it's running. + +* Then it wil execute **.openshift/action_hooks/start** to start your application. You can specify additional parameters with openshift.play.params. + +```bash + ${OPENSHIFT_REPO_DIR}target/start $PLAY_PARAMS + -Dhttp.port=${OPENSHIFT_INTERNAL_PORT} + -Dhttp.address=${OPENSHIFT_INTERNAL_IP} + -Dconfig.resource=openshift.conf +``` + +Play will then run your app in production mode. The server will listen to ${OPENSHIFT_INTERNAL_PORT} at ${OPENSHIFT_INTERNAL_IP}. + +* **.openshift/action_hooks/stop** just tries to kill the RUNNING_PID process, and then checks that no "java" process is running. If it's there, it tries five times to kill it nicely, and then if tries another five times to kill it with -SIGKILL. + +Acknowledgments +---------------------------- + +I couldn't have developed this quickstart without the help of [marekjelen](https://github.com/marekjelen) who answered [my questions on stackoverflow](http://stackoverflow.com/questions/9446275/best-approach-to-integrate-netty-with-openshift) and who also shared his [JRuby quickstart repo](https://github.com/marekjelen/openshift-jruby#readme). (I know, open source rocks!) + +It was also of great help Grant Shipley's [article on building a quickstart for openshift](https://www.redhat.com/openshift/community/blogs/how-to-create-an-openshift-github-quick-start-project). + +Play framework native support for openshift was a long awaited and pretty popular feature (you are still on time to vote for it [here](https://www.redhat.com/openshift/community/content/native-support-for-play-framework-application)). So it's a great thing that Red Hat engineers came out with this simple and powerful solution, that basically let's you implement any server able to run on a linux box. Kudos to them!!! + +Licence +---------------------------- +This project is distributed under [Apache 2 licence](http://www.apache.org/licenses/LICENSE-2.0.html). \ No newline at end of file diff --git a/conf/openshift.conf b/conf/openshift.conf new file mode 100644 index 0000000..7b4a432 --- /dev/null +++ b/conf/openshift.conf @@ -0,0 +1,45 @@ +# This is the main configuration file for the application running on openshift. +# ~~~~~ + +include "application" + +# Secret key +# ~~~~~ +# The secret key is used to secure cryptographics functions. +# If you deploy your application to several instances be sure to use the same key! +application.secret="d=ODZSG[_Y?mYq=]7a3eFSdlJ6gq>PP]/t]QF38lY;aLF;^t`uE>]vM9?30bq +# +# db.default.driver=org.h2.Driver +# db.default.url="jdbc:h2:mem:play" +# db.default.user=sa +# db.default.password= +# +# You can expose this datasource via JNDI if needed (Useful for JPA) +# db.default.jndiName=DefaultDS + +# Logger +# ~~~~~ +# You can also configure logback (http://logback.qos.ch/), by providing a logger.xml file in the conf directory . + +# Root logger: +logger.root=ERROR + +# Logger used by the framework: +logger.play=INFO + +# Logger provided to your application: +logger.application=DEBUG + +# openshift action_hooks scripts configuration +# ~~~~~ +#openshift.play.params= \ No newline at end of file