diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | STYLE-GUIDE.md | 7 | ||||
-rwxr-xr-x | bin/app-foreach-app | 23 | ||||
-rwxr-xr-x | bin/app-init | 30 | ||||
-rwxr-xr-x | bin/app-ls-apps | 27 | ||||
-rw-r--r-- | docs/app-cat-conf.txt | 5 | ||||
-rw-r--r-- | docs/app-conf.txt | 5 | ||||
-rw-r--r-- | docs/app-install-file.txt | 24 | ||||
-rw-r--r-- | docs/app-operator-pid.txt | 27 | ||||
-rw-r--r-- | docs/app.txt | 61 | ||||
-rw-r--r-- | docs/appinternals.txt | 8 | ||||
-rwxr-xr-x | lib/common | 3 | ||||
-rwxr-xr-x | libexec/app-install-file | 28 | ||||
-rwxr-xr-x | libexec/app-operator-pid | 65 |
14 files changed, 287 insertions, 27 deletions
@@ -3,6 +3,7 @@ downloads target docs/*.html docs/*.1 +docs/*.7 .app/var /*/.gitignore diff --git a/STYLE-GUIDE.md b/STYLE-GUIDE.md index c4c3a66..207b988 100644 --- a/STYLE-GUIDE.md +++ b/STYLE-GUIDE.md @@ -18,7 +18,6 @@ because the user explicitly requested so. If the user gives some form of invalid argument or there is any other error the usage should go to stderr because the user might be using pipes. - How app.sh does it ------------------ @@ -44,6 +43,12 @@ Executing Commands * http://unix.stackexchange.com/q/23026 +Parsing options +=============== + +Applications should always check for extra options or define how +they're handled. + Resources --------- diff --git a/bin/app-foreach-app b/bin/app-foreach-app new file mode 100755 index 0000000..5b5b108 --- /dev/null +++ b/bin/app-foreach-app @@ -0,0 +1,23 @@ +#!/bin/bash + +set -e +set -u + +APPSH_HOME=$(cd $(dirname "$0")/.. && pwd) + +. $APPSH_HOME/lib/common +# HEADER END + +usage_text() { + echo "usage: $usage_app [args]" +} + +IFS=" " +app-ls-apps | while read app +do + unset IFS + (cd $app; "$@") | while read line + do + echo "$app: $line" + done +done diff --git a/bin/app-init b/bin/app-init index fb4f7cd..534a876 100755 --- a/bin/app-init +++ b/bin/app-init @@ -13,7 +13,9 @@ usage_text() { } dir= -while getopts "d:" opt +prepend_config= +append_config= +while getopts "d:C:c:" opt do case $opt in d) @@ -21,6 +23,24 @@ do shift 2 OPTIND=1 ;; + C) + prepend_config=$OPTARG + if [[ ! prepend_config =~ ^/ ]] + then + prepend_config="`pwd`/$prepend_config" + fi + shift 2 + OPTIND=1 + ;; + c) + append_config=$OPTARG + if [[ ! append_config =~ ^/ ]] + then + append_config="`pwd`/$append_config" + fi + shift 2 + OPTIND=1 + ;; esac done @@ -52,7 +72,7 @@ fi mkdir -p -- "$dir" "$dir/.app" ok=no -clean_dir=`cd "$dir">/dev/null; pwd` +clean_dir=`cd "$dir" && pwd` trap '[[ $ok == yes ]] || rm -rf "$clean_dir"' EXIT cd "$dir" @@ -74,6 +94,10 @@ echo "Resolved version to $resolved_version" "$resolver" download-version -v "$resolved_version" -f .app/latest.zip -app-install-file -v "$resolved_version" -f .app/latest.zip +app-install-file \ + -v "$resolved_version" \ + ${prepend_config:+-C "$prepend_config"} \ + ${append_config:+-c "$append_config"} \ + -f .app/latest.zip ok=yes diff --git a/bin/app-ls-apps b/bin/app-ls-apps new file mode 100755 index 0000000..4adc274 --- /dev/null +++ b/bin/app-ls-apps @@ -0,0 +1,27 @@ +#!/bin/bash + +set -e +set -u + +APPSH_HOME=$(cd $(dirname "$0")/.. && pwd) + +. $APPSH_HOME/lib/common +# HEADER END + +usage_text() { + echo "usage: $usage_app [dir]" +} + +case $# in + 0) + dir=* + ;; + 1) + dir="$1/*"; shift + ;; + *) + usage + ;; +esac + +find $dir -type d -name .app | sed "s,/\.app$,," diff --git a/docs/app-cat-conf.txt b/docs/app-cat-conf.txt index fe2a5b4..57fe693 100644 --- a/docs/app-cat-conf.txt +++ b/docs/app-cat-conf.txt @@ -68,4 +68,9 @@ SEE ALSO git-config(1) +APP.SH +------ + +Part of the linkman:app[1] suite. + // vim: set ft=asciidoc: diff --git a/docs/app-conf.txt b/docs/app-conf.txt index c686960..3afeda4 100644 --- a/docs/app-conf.txt +++ b/docs/app-conf.txt @@ -20,4 +20,9 @@ DESCRIPTION Interface to the configuration values used by 'app.sh'. Modelled after the 'git-config' command. 'list' is the default command +APP.SH +------ + +Part of the linkman:app[1] suite. + // vim: set ft=asciidoc: diff --git a/docs/app-install-file.txt b/docs/app-install-file.txt new file mode 100644 index 0000000..bb7cc48 --- /dev/null +++ b/docs/app-install-file.txt @@ -0,0 +1,24 @@ +app-install-file(1) +=================== + +NAME +---- +app-install-file - Low-level installation of an app + +SYNOPSIS +-------- +[verse] +'app-operator-pid' ... + +TODOs +----- + +Tests for prepending and appending configuration:: + Missing. + +APP.SH +------ + +Part of the linkman:app[1] suite. + +// vim: set ft=asciidoc: diff --git a/docs/app-operator-pid.txt b/docs/app-operator-pid.txt new file mode 100644 index 0000000..9e0a454 --- /dev/null +++ b/docs/app-operator-pid.txt @@ -0,0 +1,27 @@ +app-operator-pid(1) +=================== + +NAME +---- +app-operator-pid - Controls the running instance of the app + +SYNOPSIS +-------- +[verse] +'app-operator-pid' ... + +TODOs +----- + +Support configurable signal to send on shutdown:: + TERM might be exessive for some apps. + +Tests for app.pid_management=launcher:: + Missing. + +APP.SH +------ + +Part of the linkman:app[1] suite. + +// vim: set ft=asciidoc: diff --git a/docs/app.txt b/docs/app.txt index c578c5d..9ab0ba7 100644 --- a/docs/app.txt +++ b/docs/app.txt @@ -10,28 +10,37 @@ SYNOPSIS [verse] 'app' <options> +DOCUMENTATION +------------- + QUICK START ~~~~~~~~~~~ - $ app init -d my-app maven org.example:my-app:1.0-SNAPSHOT - $ cd my-app - $ app start - $ app conf set app.version 1.0 - $ app upgrade - $ app restart +------------------------------------------------------------------------ +$ app init -d my-app maven org.example:my-app:1.0-SNAPSHOT +$ cd my-app +$ app start +$ app conf set app.version 1.0 +$ app upgrade +$ app restart +------------------------------------------------------------------------ INSTALLING AN APPLICATION ~~~~~~~~~~~~~~~~~~~~~~~~~ This resolved and downloads an appliaction from a Maven repository: - $ app init -d my-app maven org.example:my-app:1.0-SNAPSHOT +------------------------------------------------------------------------ +$ app init -d my-app maven org.example:my-app:1.0-SNAPSHOT +------------------------------------------------------------------------ By default it will download from the central repository, but this is not always what you want. To get it to use another repository give the `-r` option: - $ app init -d my-app maven -f http://repo.example.org/snapshots org.example:my-app:1.0-SNAPSHOT +------------------------------------------------------------------------ +$ app init -d my-app maven -f http://repo.example.org/snapshots org.example:my-app:1.0-SNAPSHOT +------------------------------------------------------------------------ UPGRADING AN APPLICATION ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -40,7 +49,9 @@ If your application is configured with the Maven resolver and the version is a SNAPSHOT version, you can use this to upgrade your application through a cron job: - $ app upgrade +------------------------------------------------------------------------ +$ app upgrade +------------------------------------------------------------------------ With the resolver will try to resolve `app.version` to the latest version. If it's change it will automatically download and install the @@ -49,12 +60,34 @@ latest version. CHANGING VERSION OF AN APPLICATION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - $ app conf set app.version 1.0 - $ app sync-version +------------------------------------------------------------------------ +$ app conf set app.version 1.0 +$ app sync-version +------------------------------------------------------------------------ `app-sync-version` will first run the resolver to resolve the version and if that has changed, it will download and install the new version. +CREATING APPS +------------- + +TODO + +CREATING HOOKS +~~~~~~~~~~~~~~ + +TODO + +CREATING LAUNCHERS +~~~~~~~~~~~~~~~~~~ + +Trick when you don't know why your app won't start: + +------------------------------------------------------------------------ +exec 1>/tmp/myapp.out +exec 2>/tmp/myapp.err +------------------------------------------------------------------------ + TODOs ----- @@ -68,8 +101,10 @@ TODOs SEE ALSO -------- -linkman:app-conf[1], linkman:app-cat-conf[1], -linkman:appinternals[1], +linkman:app-conf[1], +linkman:app-install-file[1], +linkman:app-operator-pid[1], +linkman:appinternals[1] // vim: set ft=asciidoc: diff --git a/docs/appinternals.txt b/docs/appinternals.txt index 9291fa0..ce19923 100644 --- a/docs/appinternals.txt +++ b/docs/appinternals.txt @@ -33,6 +33,14 @@ ENVIRONMENT VARIABLES --------------------- `APPSH_HOME`:: + .. + `APP_HOME`:: + .. + +APP.SH +------ + +Part of the linkman:app[1] suite. // vim: set ft=asciidoc: @@ -208,7 +208,8 @@ _get_config_file_user() { } _get_config_file_app() { - eval $1=".app/config" + local home= + eval $1="${APP_HOME-.}/.app/config" } grep_path() { diff --git a/libexec/app-install-file b/libexec/app-install-file index e2707a0..db9432b 100755 --- a/libexec/app-install-file +++ b/libexec/app-install-file @@ -9,13 +9,15 @@ APPSH_HOME=$(cd $(dirname "$0")/.. && pwd) # HEADER END usage_text() { - echo "usage: $0 -v <version> -f <file>" + echo "usage: $0 -v <version> -f <file> [-C <config>] [-c <config>]" } version= file= +prepend_config= +append_config= -while getopts "v:f:" opt +while getopts "v:f:C:c:" opt do case $opt in v) @@ -28,6 +30,16 @@ do shift 2 OPTIND=1 ;; + C) + prepend_config=$OPTARG + shift 2 + OPTIND=1 + ;; + c) + append_config=$OPTARG + shift 2 + OPTIND=1 + ;; esac done @@ -53,12 +65,24 @@ then exit 1 fi +if [ -n "$prepend_config" ] +then + debug "Prepending config from $prepend_config" + app-conf import "$prepend_config" +fi + if [ -r versions/$version/app.config ] then debug "Importing config from package" app-conf import versions/$version/app.config fi +if [ -n "$append_config" ] +then + debug "Appending config from $append_config" + app-conf import "$append_config" +fi + app-run-hook -v "$version" -h pre-install app-set-version -v "$version" diff --git a/libexec/app-operator-pid b/libexec/app-operator-pid index db1da1f..71871de 100755 --- a/libexec/app-operator-pid +++ b/libexec/app-operator-pid @@ -23,7 +23,7 @@ do_status() { } find_launcher() { - launcher=`app-conf get app.launcher` + local launcher=`app-conf get app.launcher` if [ ! -z "$launcher" ] then @@ -59,8 +59,34 @@ find_launcher() { echo $launcher } +find_pid_management() { + pid_management=`app-conf get app.pid_management` + + if [[ $pid_management == "" ]] + then + echo "appsh" + return + fi + + case "$pid_management" in + launcher) + echo "$pid_management" + ;; + *) + fatal "Invalid app.pid_management: $pid_management" + ;; + esac +} + command_start() { launcher=`find_launcher` + set -x + echo pwd=`pwd` + pid_management=`find_pid_management` + + debug "launcher=$launcher" + debug "pid_management=$pid_management" + debug "pwd=`pwd`" case `do_status` in running) @@ -69,12 +95,37 @@ command_start() { ;; esac - echo "Starting app with $launcher, pwd=`pwd`" - $launcher <&- 1<&- 2<&- & - + echo "Starting app..." + $launcher <&- 1>&- 2>&- & + PID=$! - echo "Application launched as $PID" - echo $PID > $pid_file + + case "$pid_management" in + appsh) + echo "Application launched as $PID" + echo $PID > $pid_file + ;; + launcher) + launch_timeout=`app conf get app.launch_timeout` + if [[ ! $launch_timeout =~ [0-9] ]] + then + launch_timeout=10 + fi + # the PID file is managed by the launcher, so wait for it to show up + for ((x = 0; x < "$launch_timeout"; x++)) + do + echo "Waiting for PID to show up..." + sleep 1 + if [ -r $pid_file ] + then + return 0 + fi + done + + echo "Appliation failed to start" + return 1 + ;; + esac return 0 } @@ -94,7 +145,7 @@ command_stop() { ;; esac - echo -n "Sending kill TERM to $PID, waiting for shutdown" + echo -n "Sending TERM to $PID, waiting for shutdown" kill -TERM $PID for i in {1..10} |