From 0d92ff5fd34d79b54c30c38ac41bc600acf7b7c4 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Sun, 27 Oct 2013 15:14:18 +0100 Subject: o Dropping the CSV file for using a native app config file instead. o Using apache as an example app. o Adding appstore-add-app as a utility to register appliations. --- bin/appstore-add-app | 33 ++++++++++++ bin/appstore-init | 6 +-- hooks/post-receive | 84 +++++++++++++++++++++--------- lib/common | 14 +++++ template/apps.csv | 1 - template/appstore.config | 0 test/data/Makefile | 6 +++ test/data/my-webapp/app.config | 3 +- test/data/my-webapp/root/bin/app.js | 39 -------------- test/data/my-webapp/root/bin/my-app | 20 +++++++ test/data/my-webapp/root/conf/httpd.conf | 56 ++++++++++++++++++++ test/data/my-webapp/root/conf/mime.types | 0 test/data/my-webapp/root/conf/modules.conf | 1 + test/data/my-webapp/root/conf/modules.load | 24 +++++++++ test/it.bats | 22 ++++++-- test/utils.bash | 25 +++++---- 16 files changed, 248 insertions(+), 86 deletions(-) create mode 100755 bin/appstore-add-app delete mode 100644 template/apps.csv create mode 100644 template/appstore.config create mode 100644 test/data/Makefile delete mode 100755 test/data/my-webapp/root/bin/app.js create mode 100755 test/data/my-webapp/root/bin/my-app create mode 100644 test/data/my-webapp/root/conf/httpd.conf create mode 100644 test/data/my-webapp/root/conf/mime.types create mode 100644 test/data/my-webapp/root/conf/modules.conf create mode 100644 test/data/my-webapp/root/conf/modules.load diff --git a/bin/appstore-add-app b/bin/appstore-add-app new file mode 100755 index 0000000..c190efb --- /dev/null +++ b/bin/appstore-add-app @@ -0,0 +1,33 @@ +#!/bin/bash + +set -e +set -u + +APPSTORE_HOME=$(cd $(dirname "$0")/.. && pwd) + +. $APPSTORE_HOME/lib/common +# HEADER END + +usage() { + echo "usage: $0 add-app [name] [resolver] [resolver args] [version] [state]" +} + +if [ $# -ne 5 ] +then + usage +fi + +name="$1" + +# Creating configuration file for the application +touch "$name".config +git add "$name".config + +app conf set -f appstore.config ${name}.resolver "$2" +app conf set -f appstore.config ${name}.resolver_args "$3" +app conf set -f appstore.config ${name}.version "$4" +app conf set -f appstore.config ${name}.state "$5" + +# Register the application +apps=$(app cat-conf -f appstore.config -k appstore.apps | cut -f 2- -d =) +app conf set -f appstore.config appstore.apps "$apps,$name" diff --git a/bin/appstore-init b/bin/appstore-init index 92f6ab6..029391c 100755 --- a/bin/appstore-init +++ b/bin/appstore-init @@ -9,7 +9,7 @@ APPSTORE_HOME=$(cd $(dirname "$0")/.. && pwd) # HEADER END usage() { - echo "usage [server] [name]" + echo "usage [server] [remote path] [name]" exit 1 } @@ -37,8 +37,8 @@ ret=$? set -e sed -n "s,^config: \(.*\),\1,p" $tmpfile > $conffile -repo_path=`app cat-conf -f "$conffile" -n repo.path | cut -f 2- -d =` -repo_ok=`app cat-conf -f "$conffile" -n repo.ok | cut -f 2- -d =` +repo_path=`app cat-conf -f "$conffile" -k repo.path | cut -f 2- -d =` +repo_ok=`app cat-conf -f "$conffile" -k repo.ok | cut -f 2- -d =` if [ "$ret" != 0 ] then diff --git a/hooks/post-receive b/hooks/post-receive index e0375c3..c52ac9c 100755 --- a/hooks/post-receive +++ b/hooks/post-receive @@ -10,19 +10,28 @@ APPSTORE_HOME=$(git config appstore.home) # stdin contains the refs pushed. -APPS="$(git config appstore.apps)" +conf_get() { + name=$1; shift + var=$1; shift + value=$(app cat-conf -f "$APPS/appstore.config" -k "$var" | cut -f 2- -d =) + eval ${name}='${value}' +} -REPO="$(pwd)" +check_app() { + local app=$1; shift -cd "$APPS" + dir=$app + conf_get resolver "${app}.resolver" + conf_get resolver_args "${app}.resolver_args" + conf_get version "${app}.version" + conf_get state "${app}.state" -unset GIT_DIR -git pull -q "$REPO" master + if [[ -z $resolver ]] || [[ -z $resolver_args ]] || [[ -z $version ]] || [[ -z $state ]] + then + echo "$app: invalid configuration, missing one of ${app}.resolver, ${app}.resolver_args, ${app}.version, ${app}.state" + return + fi -IFS=$'\t' -csvtool -u TAB namedcol dir,resolver,resolver_args,version,state apps.csv | \ -while read dir resolver resolver_args version state -do cd "$APPS" if [ -d "$dir" ] @@ -31,40 +40,63 @@ do dir=`pwd` old_version=$(app conf get app.version) - if [[ $new_version == $old_version ]] + if [[ $new_version = $old_version ]] then + echo "$dir: already at $version" continue fi - echo "Updating $dir to $version" + echo "$dir: updating to $version" app conf set app.version "$version" app update else - echo "New application: $dir" - app init -d "$dir" "$resolver" "$resolver_args" + echo "$dir: new app" + if [[ -r ${dir}.config ]] + then + append_config="${dir}.config" + fi + + app init \ + ${append_config:+-c} $append_config \ + -d "$dir" \ + "$resolver" "$resolver_args" cd "$dir" dir=`pwd` fi cd "$dir" - if [[ $state == enabled ]] + + if [[ $state = enabled ]] then - cmd=start - title="Starting" + app start || true else - cmd=stop - title="Stopping" + app stop || true fi +} - echo "$title appliation" - set +e - app $cmd - ret=$? - set -e +APPS="$(git config appstore.apps)" - if [[ $ret != 0 ]] +REPO="$(pwd)" + +cd "$APPS" + +unset GIT_DIR +git pull -q "$REPO" master + +conf_get apps appstore.apps +apps=$(echo "$apps" | sed "s/, */,/g") + +IFS=, +for app in $apps +do + if [[ $app = "" ]] then - echo "$cmd command failed." + continue fi + + assert_valid_app_name "$app" + + check_app "$app" || true done -unset IFS + +echo "Done." diff --git a/lib/common b/lib/common index 473c8b1..2214480 100755 --- a/lib/common +++ b/lib/common @@ -62,3 +62,17 @@ grep_path() { find `echo $path | tr : " "` -type f -executable 2>/dev/null | (egrep "$regex" || exit 0) } + +assert_valid_app_name() { + local app="$1"; shift + + local re="^[a-zA-Z][a-zA-Z0-9]*$" + if [[ ! $app =~ $re ]] + then + fatal "Invalid app name: \"$app\"" + fi +} + +# Save for later +usage_app=${0##*/} +echo_debug=${echo_debug-no} diff --git a/template/apps.csv b/template/apps.csv deleted file mode 100644 index 3637e0e..0000000 --- a/template/apps.csv +++ /dev/null @@ -1 +0,0 @@ -dir,resolver,resolver_args,version,state diff --git a/template/appstore.config b/template/appstore.config new file mode 100644 index 0000000..e69de29 diff --git a/test/data/Makefile b/test/data/Makefile new file mode 100644 index 0000000..ad61a15 --- /dev/null +++ b/test/data/Makefile @@ -0,0 +1,6 @@ +all: my-webapp.zip + +my-webapp.zip: + @rm -f my-webapp.zip + @(cd my-webapp; zip -q -r ../my-webapp.zip .) +.PHONY: my-webapp.zip diff --git a/test/data/my-webapp/app.config b/test/data/my-webapp/app.config index 40cbaa0..3a68978 100644 --- a/test/data/my-webapp/app.config +++ b/test/data/my-webapp/app.config @@ -1 +1,2 @@ -app.bin=app.js +app.pid_management=launcher +app.launch_timeout=2 diff --git a/test/data/my-webapp/root/bin/app.js b/test/data/my-webapp/root/bin/app.js deleted file mode 100755 index 992a701..0000000 --- a/test/data/my-webapp/root/bin/app.js +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env nodejs - -var http = require("http"), - url = require("url"), - path = require("path"), - fs = require("fs") - port = process.env.PORT || 8888; - -http.createServer(function(request, response) { - - var uri = url.parse(request.url).pathname - , filename = path.join(process.cwd(), uri); - - path.exists(filename, function(exists) { - if(!exists) { - response.writeHead(404, {"Content-Type": "text/plain"}); - response.write("404 Not Found\n"); - response.end(); - return; - } - - if (fs.statSync(filename).isDirectory()) filename += '/index.html'; - - fs.readFile(filename, "binary", function(err, file) { - if(err) { - response.writeHead(500, {"Content-Type": "text/plain"}); - response.write(err + "\n"); - response.end(); - return; - } - - response.writeHead(200); - response.write(file, "binary"); - response.end(); - }); - }); -}).listen(parseInt(port, 10)); - -console.log("Static file server running at\n => http://localhost:" + port + "/\nCTRL + C to shutdown"); diff --git a/test/data/my-webapp/root/bin/my-app b/test/data/my-webapp/root/bin/my-app new file mode 100755 index 0000000..e3fb305 --- /dev/null +++ b/test/data/my-webapp/root/bin/my-app @@ -0,0 +1,20 @@ +#!/bin/bash + +export BASEDIR=`pwd` + +exec 1>/tmp/stdout +exec 2>/tmp/stderr + +mkdir -p "$BASEDIR/locks" +mkdir -p "$BASEDIR/logs" + +set -x +export APACHE_LOCK_DIR="$BASEDIR/locks" +export APACHE_PID_FILE="$(cd $BASEDIR/../../../.app && pwd)/pid" +export APACHE_LOG_DIR="$BASEDIR/logs" + +export MODULES=/usr/lib/apache2/modules + +export PORT=$(app conf get myapp.port) + +exec /usr/sbin/apache2 -DPORT="$PORT" -f "$BASEDIR/conf/httpd.conf" diff --git a/test/data/my-webapp/root/conf/httpd.conf b/test/data/my-webapp/root/conf/httpd.conf new file mode 100644 index 0000000..4a1e775 --- /dev/null +++ b/test/data/my-webapp/root/conf/httpd.conf @@ -0,0 +1,56 @@ +ServerRoot ${BASEDIR} +Mutex file:locks default +PidFile ${APACHE_PID_FILE} +Timeout 300 +KeepAlive On +MaxKeepAliveRequests 100 +KeepAliveTimeout 5 + +#User ${APACHE_RUN_USER} +#Group ${APACHE_RUN_GROUP} + +HostnameLookups Off +ErrorLog logs/error.log +LogLevel warn + +Include conf/modules.load +Include conf/modules.conf + +Listen ${PORT} + + + StartServers 5 + MinSpareServers 5 + MaxSpareServers 10 + MaxRequestWorkers 150 + MaxConnectionsPerChild 0 + + + + Options FollowSymLinks + AllowOverride None + Require all denied + + + + Options Indexes FollowSymLinks + AllowOverride None + Require all granted + + +AccessFileName .htaccess + + + Require all denied + + +LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined +LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined +LogFormat "%h %l %u %t \"%r\" %>s %O" common +LogFormat "%{Referer}i -> %U" referer +LogFormat "%{User-agent}i" agent + +#IncludeOptional conf-enabled/*.conf +#IncludeOptional sites-enabled/*.conf + +# vim: syntax=apache ts=4 sw=4 sts=4 sr noet diff --git a/test/data/my-webapp/root/conf/mime.types b/test/data/my-webapp/root/conf/mime.types new file mode 100644 index 0000000..e69de29 diff --git a/test/data/my-webapp/root/conf/modules.conf b/test/data/my-webapp/root/conf/modules.conf new file mode 100644 index 0000000..f791286 --- /dev/null +++ b/test/data/my-webapp/root/conf/modules.conf @@ -0,0 +1 @@ +TypesConfig conf/mime.types diff --git a/test/data/my-webapp/root/conf/modules.load b/test/data/my-webapp/root/conf/modules.load new file mode 100644 index 0000000..eafc5b5 --- /dev/null +++ b/test/data/my-webapp/root/conf/modules.load @@ -0,0 +1,24 @@ +LoadModule access_compat_module /usr/lib/apache2/modules/mod_access_compat.so +LoadModule alias_module /usr/lib/apache2/modules/mod_alias.so +LoadModule auth_basic_module /usr/lib/apache2/modules/mod_auth_basic.so +LoadModule authn_core_module /usr/lib/apache2/modules/mod_authn_core.so +LoadModule authn_file_module /usr/lib/apache2/modules/mod_authn_file.so +LoadModule authz_core_module /usr/lib/apache2/modules/mod_authz_core.so +LoadModule authz_groupfile_module /usr/lib/apache2/modules/mod_authz_groupfile.so +LoadModule authz_host_module /usr/lib/apache2/modules/mod_authz_host.so +LoadModule authz_user_module /usr/lib/apache2/modules/mod_authz_user.so +LoadModule autoindex_module /usr/lib/apache2/modules/mod_autoindex.so +LoadModule cgi_module /usr/lib/apache2/modules/mod_cgi.so +LoadModule deflate_module /usr/lib/apache2/modules/mod_deflate.so +LoadModule dir_module /usr/lib/apache2/modules/mod_dir.so +LoadModule dnssd_module /usr/lib/apache2/modules/mod_dnssd.so +LoadModule env_module /usr/lib/apache2/modules/mod_env.so +LoadModule expires_module /usr/lib/apache2/modules/mod_expires.so +LoadModule filter_module /usr/lib/apache2/modules/mod_filter.so +LoadModule mime_module /usr/lib/apache2/modules/mod_mime.so +LoadModule mpm_prefork_module /usr/lib/apache2/modules/mod_mpm_prefork.so +LoadModule negotiation_module /usr/lib/apache2/modules/mod_negotiation.so +LoadModule php5_module /usr/lib/apache2/modules/libphp5.so +LoadModule reqtimeout_module /usr/lib/apache2/modules/mod_reqtimeout.so +LoadModule setenvif_module /usr/lib/apache2/modules/mod_setenvif.so +LoadModule status_module /usr/lib/apache2/modules/mod_status.so diff --git a/test/it.bats b/test/it.bats index 406d5fc..df0d4b9 100644 --- a/test/it.bats +++ b/test/it.bats @@ -4,8 +4,8 @@ load utils @test "Happy day" { - mkzip my-webapp - install_artifact "my-webapp" +# describe "Installing Maven artifacts" +# install_artifact "my-webapp" # install_artifact "my-webapp" 1.0 cd $BATS_TMPDIR @@ -13,16 +13,28 @@ load utils mkdir -p client server cd client + describe "appstore init" appstore init "localhost" "$BATS_TMPDIR/appstore/server" "mysetup" cd mysetup + describe "appstore add-app" # Making assertions easier. git config user.name "Test Case" git config user.email tester@example.org - echo "frontend,maven,org.example:my-webapp:1.0-SNAPSHOT,1.0-SNAPSHOT,enabled" >> apps.csv - echo "backend,maven,org.example:my-webapp:1.0-SNAPSHOT,1.0-SNAPSHOT,enabled" >> apps.csv - echo "left,maven,org.example:my-webapp:1.0-SNAPSHOT,1.0-SNAPSHOT,disabled" >> apps.csv + appstore add-app frontend file $BATS_TEST_DIRNAME/data/my-webapp.zip 1.0-SNAPSHOT enabled + app conf set -f frontend.config myapp.port 8880 + + appstore add-app backend file $BATS_TEST_DIRNAME/data/my-webapp.zip 1.0-SNAPSHOT enabled + app conf set -f backend.config myapp.port 8881 + + appstore add-app left maven org.example:my-webapp:1.0-SNAPSHOT 1.0-SNAPSHOT disabled + app conf set -f left.config myapp.port 8882 + + appstore add-app right maven org.example:my-webapp:1.0-SNAPSHOT 1.0-SNAPSHOT disabled + # no myapp.port + + describe "git commit & push" git commit -m "o Adding app-1." -a git push cloud master eq "ssh://localhost$BATS_TMPDIR/appstore/server/repos/mysetup" `git config remote.cloud.url` diff --git a/test/utils.bash b/test/utils.bash index cd6fcf0..4c7e2c8 100644 --- a/test/utils.bash +++ b/test/utils.bash @@ -8,10 +8,18 @@ exit_usage_wrong=0 setup() { ORIG_PATH=$PATH - APPSTORE_HOME=$(cd $BATS_TEST_DIRNAME/..; echo `pwd`) + APPSTORE_HOME=$(cd $BATS_TEST_DIRNAME/.. && echo `pwd`) PATH=/bin:/usr/bin PATH=$PATH:$APPSTORE_HOME + APPSH_HOME=$(cd $BATS_TEST_DIRNAME/../../app.sh && echo `pwd`) + if [[ ! -x $APPSH_HOME/app ]] + then + echo "app.sh has to be available as ../app.sh" + exit 1 + fi + PATH=$PATH:$APPSH_HOME + rm -rf $BATS_TMPDIR/appstore mkdir $BATS_TMPDIR/appstore @@ -23,6 +31,9 @@ setup() { REPO_URL="file://$REPO" FIXED_REPO_URL="file://`fix_path $REPO`" + cd $BATS_TEST_DIRNAME/data + make + if [ "`declare -f setup_inner >/dev/null; echo $?`" = 0 ] then setup_inner @@ -35,14 +46,6 @@ echo_lines() { echo status=$status } -mkzip() { -( - cd $BATS_TEST_DIRNAME/data/$1 - rm -f ../$1.zip - zip -qr ../$1.zip * -) -} - install_artifact() { local artifactId=${1}; shift local version=${1-1.0-SNAPSHOT} @@ -56,7 +59,7 @@ check_status=yes app() { echo app $@ - run $APPSTORE_HOME/app $@ + run $APPSH_HOME/app $@ echo_lines if [ "$check_status" = yes ] @@ -68,7 +71,7 @@ app() { } app_libexec() { - local x=`PATH=$APPSTORE_HOME/libexec:/bin:/usr/bin which $1` + local x=`PATH=$APPSH_HOME/libexec:/bin:/usr/bin which $1` echo libexec/$@ shift -- cgit v1.2.3