From 5dd16e14dd41f1565687142ba7cefa7c4cf64658 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Tue, 12 Nov 2013 13:39:41 +0100 Subject: wip --- .gitignore | 1 + Makefile | 9 ++- bin/appstore-add-app | 2 + bin/appstore-init | 11 +++- docs/appstore.txt | 6 ++ hooks/post-receive | 89 +-------------------------- lib/common | 35 +++++++++-- libexec/appstore-init-server | 50 --------------- libexec/appstore-server-init | 50 +++++++++++++++ libexec/appstore-server-sync | 99 ++++++++++++++++++++++++++++++ test/appstore-server-sync.bats | 48 +++++++++++++++ test/data/Makefile | 10 +-- test/data/my-app/app.config | 1 + test/data/my-app/root/bin/my-app | 17 +++++ test/data/my-webapp/app.config | 2 - 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 | 5 +- test/utils.bash | 13 ++++ 22 files changed, 292 insertions(+), 257 deletions(-) create mode 100644 docs/appstore.txt delete mode 100755 libexec/appstore-init-server create mode 100755 libexec/appstore-server-init create mode 100755 libexec/appstore-server-sync create mode 100644 test/appstore-server-sync.bats create mode 100644 test/data/my-app/app.config create mode 100755 test/data/my-app/root/bin/my-app delete mode 100644 test/data/my-webapp/app.config delete mode 100755 test/data/my-webapp/root/bin/my-app delete mode 100644 test/data/my-webapp/root/conf/httpd.conf delete mode 100644 test/data/my-webapp/root/conf/mime.types delete mode 100644 test/data/my-webapp/root/conf/modules.conf delete mode 100644 test/data/my-webapp/root/conf/modules.load diff --git a/.gitignore b/.gitignore index c4c4ffc..5fe9dfa 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ *.zip +test/bats diff --git a/Makefile b/Makefile index ba3a58e..9759eab 100644 --- a/Makefile +++ b/Makefile @@ -8,18 +8,21 @@ TESTS=$(addprefix test-,$(BATS)) test-%: @echo === $@ - @bats $(patsubst test-%,test/%,$@) + @PATH=test/bats/bin:$(PATH) bats $(patsubst test-%,test/%,$@) show-tests: @echo BATS=$(BATS) @echo TESTS=$(TESTS) @echo $(addprefix set_header-,$(BINS)) -test: $(TESTS) +test: test/bats $(TESTS) .PHONY: test +test/bats: + cd test && git clone git://github.com/sstephenson/bats.git + docs: - @make -C docs + #@make -C docs .PHONY: docs define set_header diff --git a/bin/appstore-add-app b/bin/appstore-add-app index c190efb..2b9ed19 100755 --- a/bin/appstore-add-app +++ b/bin/appstore-add-app @@ -31,3 +31,5 @@ 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" + +git add appstore.config diff --git a/bin/appstore-init b/bin/appstore-init index 029391c..b721eee 100755 --- a/bin/appstore-init +++ b/bin/appstore-init @@ -19,9 +19,12 @@ then fi server=$1; shift -repos=$1; shift +root=$1; shift name=$1; shift +repos=$root/repos +appstores=$root/appstores + if [ -e "$name" ] then echo "$name already exist!" @@ -32,7 +35,11 @@ tmpfile=tmpfile$$ conffile=conffile$$ echo "Creating remote appstore..." set +e -ssh "$server" "$APPSTORE_HOME/libexec/appstore-init-server" "$repos" "$name" > "$tmpfile" 2>&1 +ssh "$server" \ + "$APPSTORE_HOME/libexec/appstore-server-init" \ + "$repos" \ + "$appstores" \ + "$name" > "$tmpfile" 2>&1 ret=$? set -e diff --git a/docs/appstore.txt b/docs/appstore.txt new file mode 100644 index 0000000..2269bd7 --- /dev/null +++ b/docs/appstore.txt @@ -0,0 +1,6 @@ +TODO +==== + +hooks:: + pre-stop, post-stop, pre-start, post-start. Executed before any + action is taken on apps. diff --git a/hooks/post-receive b/hooks/post-receive index c52ac9c..7cc91f5 100755 --- a/hooks/post-receive +++ b/hooks/post-receive @@ -10,93 +10,10 @@ APPSTORE_HOME=$(git config appstore.home) # stdin contains the refs pushed. -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}' -} - -check_app() { - local app=$1; shift - - dir=$app - conf_get resolver "${app}.resolver" - conf_get resolver_args "${app}.resolver_args" - conf_get version "${app}.version" - conf_get state "${app}.state" - - 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 - - cd "$APPS" - - if [ -d "$dir" ] - then - cd "$dir" - dir=`pwd` - old_version=$(app conf get app.version) - - if [[ $new_version = $old_version ]] - then - echo "$dir: already at $version" - continue - fi - - echo "$dir: updating to $version" - app conf set app.version "$version" - app update - else - 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 ]] - then - app start || true - else - app stop || true - fi -} - +#REPO="$(pwd)" +REPO="$GIT_DIR" APPS="$(git config appstore.apps)" -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 - continue - fi - - assert_valid_app_name "$app" - - check_app "$app" || true -done -echo "Done." +exec appstore server-sync "$REPO" "$APPS" diff --git a/lib/common b/lib/common index 2214480..f44dde8 100755 --- a/lib/common +++ b/lib/common @@ -9,7 +9,17 @@ then exit 1 fi -PATH=$APPSH_HOME:$PATH +##################################################################### +# Common init + +PATH=$APPSH_HOME:$APPSTORE_HOME:$PATH + +# Save for later +usage_app=${0##*/} +echo_debug=${echo_debug-no} + +##################################################################### +# Utilities show_help() { message=${1-} @@ -66,13 +76,28 @@ grep_path() { assert_valid_app_name() { local app="$1"; shift - local re="^[a-zA-Z][a-zA-Z0-9]*$" + 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} +##################################################################### +# + +make_absolute() { + local name=$1; shift + local value=${!name} + + if [[ $value = "." ]] + then + eval ${name}="$(pwd)" + elif [[ -e ${value} ]] + then + bn=$(basename ${value}) + path=$(cd ${value}/.. && pwd) + + eval ${name}=${path}/${bn} + fi +} diff --git a/libexec/appstore-init-server b/libexec/appstore-init-server deleted file mode 100755 index 1417469..0000000 --- a/libexec/appstore-init-server +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/bash - -set -e -set -u - -APPSTORE_HOME=$(cd $(dirname "$0")/.. && pwd) - -. $APPSTORE_HOME/lib/common -# HEADER END - -root=$1; shift -name=$1; shift - -echo "Creating appstore $name" - -repo="$root/repos/$name" -apps="$root/appstores/$name" - -if [ -e "$repo" ] -then - echo "$name already exist!" - exit 1 -fi - -# Create the git repository -git init -q --bare "$repo" - -# Clone the repository -git init -q "$apps" -cd "$apps" - -# Copy the template project -cp -r "$APPSTORE_HOME/template/"* . -git add -A -git config user.name "Appstore Bot" -git config user.email nobody@example.org -git commit -q -m "Created new appstore: $name." -git push -q "$repo" master -cd .. - -# Install the hooks -cd "$repo" -pwd -rm hooks/* -rmdir hooks -ln -s "$APPSTORE_HOME/hooks" hooks -git config appstore.home "$APPSTORE_HOME" -git config appstore.apps "$apps" - -echo "config: repo.path=$repo" diff --git a/libexec/appstore-server-init b/libexec/appstore-server-init new file mode 100755 index 0000000..a220f83 --- /dev/null +++ b/libexec/appstore-server-init @@ -0,0 +1,50 @@ +#!/bin/bash + +set -e +set -u + +APPSTORE_HOME=$(cd $(dirname "$0")/.. && pwd) + +. $APPSTORE_HOME/lib/common +# HEADER END + +repos=$1; shift +appstores=$1; shift +name=$1; shift + +echo "Creating appstore: $name" + +repo="$repos/$name" +appstore="$appstores/$name" + +if [ -e "$repo" ] +then + echo "$name already exist!" + exit 1 +fi + +# Create the git repository +git init -q --bare "$repo" + +# Clone the repository +git init -q "$appstore" +cd "$appstore" + +# Copy the template project +cp -r "$APPSTORE_HOME/template/"* . +git add -A +git config user.name "Appstore Bot" +git config user.email nobody@example.org +git commit -q -m "Created new appstore: $name." +git push -q "$repo" master +cd .. + +# Install the hooks +cd "$repo" +rm hooks/* +rmdir hooks +ln -s "$APPSTORE_HOME/hooks" hooks +git config appstore.home "$APPSTORE_HOME" +git config appstore.apps "$appstore" + +echo "config: repo.path=$repo" diff --git a/libexec/appstore-server-sync b/libexec/appstore-server-sync new file mode 100755 index 0000000..5938962 --- /dev/null +++ b/libexec/appstore-server-sync @@ -0,0 +1,99 @@ +#!/bin/bash + +set -e +set -u + +APPSTORE_HOME=$(cd $(dirname "$0")/.. && pwd) + +. $APPSTORE_HOME/lib/common +# HEADER END + +conf_get() { + name=$1; shift + var=$1; shift + value=$(app cat-conf -f "$APPSTORE/appstore.config" -k "$var" | cut -f 2- -d =) + eval ${name}='${value}' +} + +check_app() { + local app=$1; shift + + dir=$app + conf_get resolver "${app}.resolver" + conf_get resolver_args "${app}.resolver_args" + conf_get version "${app}.version" + conf_get state "${app}.state" + + 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 + + cd "$APPSTORE" + + if [[ -d $dir ]] + then + cd "$dir" + dir=`pwd` + + if [[ -r $APPSTORE/$app.config ]] + then + app conf import $APPSTORE/$app.config + fi + app conf set app.version "$version" + app upgrade + else + 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 ]] + then + app start || true + else + app stop || true + fi +} + +REPO="$1"; shift +APPSTORE="$1"; shift + +make_absolute REPO +make_absolute APPSTORE + +cd "$APPSTORE" + +# This should probably be a git fetch && checkout origin/HEAD --force +# or whatever. +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 + continue + fi + + assert_valid_app_name "$app" + + check_app "$app" || true +done + +echo "Done." diff --git a/test/appstore-server-sync.bats b/test/appstore-server-sync.bats new file mode 100644 index 0000000..7295f3d --- /dev/null +++ b/test/appstore-server-sync.bats @@ -0,0 +1,48 @@ +#!/usr/bin/env bats +# vim: set filetype=sh: + +load utils + +@test "Full test" { + cd $BATS_TMPDIR + rm -rf appstore-server-sync + mkdir -p appstore-server-sync/{repos,appstores,wc} + cd appstore-server-sync + + appstore server-init `pwd`/{repos,appstores} my-store + + git clone repos/my-store wc + cd wc + git config user.name "Test Case" + git config user.email tester@example.org + appstore add-app app-a file $BATS_TEST_DIRNAME/data/my-app.zip 1.0-SNAPSHOT disabled + git commit -a -m wip + cd .. + + appstore server-sync `pwd`/wc `pwd`/appstores/my-store + + # Check that the installed conf matches the one from the app + ( + cd appstores/my-store + app cat-conf -g my-app -f app-a/.app/config + eq '${lines[0]}' "my-app.awesome=true" + eq '${#lines[*]}' 1 + ) + + # Add some configuration to be merged into the app + ( + cd wc + echo my-app.extra=true >> app-a.config + git commit -a -m "extra config" + ) + + appstore server-sync `pwd`/wc `pwd`/appstores/my-store + + ( + cd appstores/my-store + app cat-conf -g my-app -f app-a/.app/config + eq '${lines[0]}' "my-app.awesome=true" + eq '${lines[1]}' "my-app.extra=true" + eq '${#lines[*]}' 2 + ) +} diff --git a/test/data/Makefile b/test/data/Makefile index ad61a15..4d5968b 100644 --- a/test/data/Makefile +++ b/test/data/Makefile @@ -1,6 +1,6 @@ -all: my-webapp.zip +all: my-app.zip -my-webapp.zip: - @rm -f my-webapp.zip - @(cd my-webapp; zip -q -r ../my-webapp.zip .) -.PHONY: my-webapp.zip +my-app.zip: + @rm -f my-app.zip + @(cd my-app; zip -q -r ../my-app.zip .) +.PHONY: my-app.zip diff --git a/test/data/my-app/app.config b/test/data/my-app/app.config new file mode 100644 index 0000000..5980d80 --- /dev/null +++ b/test/data/my-app/app.config @@ -0,0 +1 @@ +my-app.awesome=true diff --git a/test/data/my-app/root/bin/my-app b/test/data/my-app/root/bin/my-app new file mode 100755 index 0000000..2416bbf --- /dev/null +++ b/test/data/my-app/root/bin/my-app @@ -0,0 +1,17 @@ +#!/bin/bash + +LOGS="$APP_HOME/logs" + +mkdir -p "$LOGS" +logfile=$LOGS/my-app.out +exec >> $logfile +exec 2>&1 + +end=$(app conf get my-app.end) +end=${end:-10} + +for i in seq 1 $end +do + echo "`date`: working..." + sleep 1 +done diff --git a/test/data/my-webapp/app.config b/test/data/my-webapp/app.config deleted file mode 100644 index 3a68978..0000000 --- a/test/data/my-webapp/app.config +++ /dev/null @@ -1,2 +0,0 @@ -app.pid_management=launcher -app.launch_timeout=2 diff --git a/test/data/my-webapp/root/bin/my-app b/test/data/my-webapp/root/bin/my-app deleted file mode 100755 index e3fb305..0000000 --- a/test/data/my-webapp/root/bin/my-app +++ /dev/null @@ -1,20 +0,0 @@ -#!/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 deleted file mode 100644 index 4a1e775..0000000 --- a/test/data/my-webapp/root/conf/httpd.conf +++ /dev/null @@ -1,56 +0,0 @@ -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 deleted file mode 100644 index e69de29..0000000 diff --git a/test/data/my-webapp/root/conf/modules.conf b/test/data/my-webapp/root/conf/modules.conf deleted file mode 100644 index f791286..0000000 --- a/test/data/my-webapp/root/conf/modules.conf +++ /dev/null @@ -1 +0,0 @@ -TypesConfig conf/mime.types diff --git a/test/data/my-webapp/root/conf/modules.load b/test/data/my-webapp/root/conf/modules.load deleted file mode 100644 index eafc5b5..0000000 --- a/test/data/my-webapp/root/conf/modules.load +++ /dev/null @@ -1,24 +0,0 @@ -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 df0d4b9..0542ddb 100644 --- a/test/it.bats +++ b/test/it.bats @@ -35,8 +35,7 @@ load utils # no myapp.port describe "git commit & push" - git commit -m "o Adding app-1." -a - git push cloud master + run git commit -m "o Adding app-1." -a + run git push cloud master eq "ssh://localhost$BATS_TMPDIR/appstore/server/repos/mysetup" `git config remote.cloud.url` - eq 1 2 } diff --git a/test/utils.bash b/test/utils.bash index 4c7e2c8..8b23210 100644 --- a/test/utils.bash +++ b/test/utils.bash @@ -87,6 +87,19 @@ app_libexec() { check_status=yes } +appstore() { + echo appstore $@ + run $APPSTORE_HOME/appstore $@ + echo_lines + + if [ "$check_status" = yes ] + then + eq '$status' 0 + fi + + check_status=yes +} + fix_path_uname=`uname -s` fix_path() { case $fix_path_uname in -- cgit v1.2.3