aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--STYLE-GUIDE.md7
-rwxr-xr-xbin/app-foreach-app23
-rwxr-xr-xbin/app-init30
-rwxr-xr-xbin/app-ls-apps27
-rw-r--r--docs/app-cat-conf.txt5
-rw-r--r--docs/app-conf.txt5
-rw-r--r--docs/app-install-file.txt24
-rw-r--r--docs/app-operator-pid.txt27
-rw-r--r--docs/app.txt61
-rw-r--r--docs/appinternals.txt8
-rwxr-xr-xlib/common3
-rwxr-xr-xlibexec/app-install-file28
-rwxr-xr-xlibexec/app-operator-pid65
14 files changed, 287 insertions, 27 deletions
diff --git a/.gitignore b/.gitignore
index 5299b29..b6d1d32 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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:
diff --git a/lib/common b/lib/common
index 663bf45..b52da43 100755
--- a/lib/common
+++ b/lib/common
@@ -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}