diff options
-rw-r--r-- | STYLE-GUIDE.md | 17 | ||||
-rwxr-xr-x | app | 28 | ||||
-rwxr-xr-x | bin/app-init | 4 | ||||
-rw-r--r-- | build.log | 0 | ||||
-rw-r--r-- | lib/common | 75 | ||||
-rwxr-xr-x | libexec/app-cat-conf | 7 | ||||
-rwxr-xr-x | libexec/app-install-file | 170 | ||||
-rwxr-xr-x | libexec/app-method-pid (renamed from bin/pid-method) | 0 | ||||
-rwxr-xr-x | libexec/app-operate | 68 | ||||
-rwxr-xr-x | libexec/app-run-hook | 49 | ||||
-rwxr-xr-x | libexec/app-set-version | 50 | ||||
-rwxr-xr-x | test/app-init.bats | 11 | ||||
-rwxr-xr-x | test/data/app-a/hooks/post-install | 5 | ||||
-rw-r--r-- | test/data/app-a/scripts/postinstall | 21 | ||||
-rw-r--r-- | test/utils.bash | 1 |
15 files changed, 265 insertions, 241 deletions
diff --git a/STYLE-GUIDE.md b/STYLE-GUIDE.md new file mode 100644 index 0000000..21f1523 --- /dev/null +++ b/STYLE-GUIDE.md @@ -0,0 +1,17 @@ +Style Guide +----------- + +Usage +===== + +* Always echo to `stderr`. +* Exit with code 1. +* Enclose required arguments in angle brackets: `-v <version>` +* Enclose optional arguments in square brackets: `[-h hook]` + + usage() { + echo "usage: $0 -v <version> [-h hook]" + exit 1 + } + + @@ -1,19 +1,5 @@ #!/bin/bash -e -PRG="$0" -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi -done - -APPSH_HOME=`dirname "$PRG"` -APPSH_HOME=`cd "$APPSH_HOME" && pwd` - usage() { if [ -n "$1" ] then @@ -30,6 +16,20 @@ usage() { echo "Run $0 -h <group> for more help" >&2 } +PRG="$0" +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi +done + +APPSH_HOME=`dirname "$PRG"` +APPSH_HOME=`cd "$APPSH_HOME" && pwd` + . $APPSH_HOME/lib/common while getopts "h" opt diff --git a/bin/app-init b/bin/app-init index cca82e1..d61f989 100755 --- a/bin/app-init +++ b/bin/app-init @@ -48,7 +48,7 @@ fi # TODO: install a trap handler and rm -rf "$dir" -resolver=`grep_path "/app-resolver-$resolver_name$" "$PATH:$APPSH_HOME/libexec" | head -n 1` +resolver=`grep_path "/app-resolver-$resolver_name$" "$PATH" | head -n 1` if [ -z "$resolver" ] then @@ -75,3 +75,5 @@ fi echo "Resolved version to $version" "$resolver" download-version -v "$version" -f .app/latest.zip + +app-install-file -v "$version" -f .app/latest.zip diff --git a/build.log b/build.log new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/build.log @@ -2,13 +2,17 @@ assert_is_app() { local check_link=yes + local version= - while getopts "C" opt + while getopts "Cv:" opt do case $opt in C) check_link=no ;; + v) + version=$OPTARG + ;; esac done @@ -22,12 +26,24 @@ assert_is_app() { then if [ ! -e current ] then - echo "Missing 'current' link." >&2 - exit 1 + fatal "Missing 'current' link." >&2 + fi + fi + + if [[ $version != "" ]] + then + if [[ ! -d versions/$version ]] + then + fatal "No such version: $version" fi fi } +fatal() { + echo "$usage_app: fatal: $@" 2>&1 + exit 1 +} + list_apps() { local filter_name=$1; shift local filter_instnace=$1; shift @@ -121,27 +137,33 @@ grep_path() { # TODO: set ulimit # TODO: set umask # TODO: change group newgrp/sg +# usage: run_app [-v version] [bin to execute] run_app() { - local name=$1; shift - local instance=$1; shift - local bin=$1; shift - local method=$1; shift - - assert_is_instance operate_usage "$name" "$instance" + version= + while getopts "v:" opt + do + case $opt in + v) + version=$OPTARG + shift 2 + OPTIND=1 + ;; + esac + done - local x="" - if [ ! -z "$APPSH_APPS" ] - then - x="$APPSH_APPS/" - fi + local bin=$1; shift + local e=`app-cat-conf -f .app/config -n "env\..*" | cut -f 2- -d .` ( - cd $x$name/$instance - APPSH_INSTANCE_HOME=`pwd` - cd current + if [[ $version == "" ]] + then + assert_is_app + cd current + else + assert_is_app -v "$version" + cd "versions/$version" + fi - local e=`$APPSH_HOME/bin/app-cat-conf -f $apps/$name/$instance/current/etc/app.conf -g env | cut -f 2- -d .` - #e="`get_conf_in_group $apps $name $instance env`" # This magically get the expansion of $u correct. IFS=" " @@ -152,12 +174,7 @@ run_app() { PATH=/bin:/usr/bin \ $e \ PWD="$PWD" \ - APPSH_METHOD=$method \ - APPSH_APPS=$apps \ APPSH_HOME=$APPSH_HOME \ - APPSH_NAME=$name \ - APPSH_INSTANCE=$instance \ - APPSH_INSTANCE_HOME=$APPSH_INSTANCE_HOME \ $bin "$@" local ret=$? set +x @@ -166,3 +183,13 @@ run_app() { exit $ret ) } + +##################################################################### +# Common init + +# Add the app-* apps to PATH. They're added last to allow the user to +# overload their implementations. +PATH=$PATH:$APPSH_HOME/bin:$APPSH_HOME/libexec + +# Save for later +usage_app=$0 diff --git a/libexec/app-cat-conf b/libexec/app-cat-conf index 5da435e..5b1c614 100755 --- a/libexec/app-cat-conf +++ b/libexec/app-cat-conf @@ -38,6 +38,13 @@ fi APPSH_DEFAULT_CONFIG=${APPSH_DEFAULT_CONFIG-$APPSH_HOME/lib/default-config} +# TODO: find config files in the paths above $file's paths and perhaps /etc/appsh/config + +if [[ ! -r $file ]] +then + fatal "No such file: $file" +fi + # The awk script makes sure each key only appears once cat "$file" "$APPSH_DEFAULT_CONFIG" | \ sed -n -e "$filter" | \ diff --git a/libexec/app-install-file b/libexec/app-install-file index a0d929a..1e3edb8 100755 --- a/libexec/app-install-file +++ b/libexec/app-install-file @@ -8,127 +8,53 @@ APPSH_HOME=$(cd $(dirname "$0")/.. && pwd) . $APPSH_HOME/lib/common # HEADER END -calculate_md5() { - local file="$1"; shift - - md5sum "$file" | cut -c 1-32 -} - -# TODO: support file:// repositories -# TODO: look in the local repository first -get() { - local url=$1 - local file=$2 - local exit - - curl -o $file $url -D curl.tmp - - exit=`grep "^HTTP/[0-9]\.[0-9] 200 .*" curl.tmp >/dev/null; echo $?` - head=`head -n 1 curl.tmp` - rm -f curl.tmp - if [ "$exit" != 0 ] - then - echo "Unable to download $url: $head" >&2 - exit 1 - fi -} - -resolve_snapshot() { - local groupId=$1; shift - local groupIdSlash=$1; shift - local artifactId=$1; shift - local version=$1; shift - - local metadata=$apps/.app/var/download/$groupId-$artifactId-$version-metadata.xml - local base_url=$repo/$groupIdSlash/$artifactId/$version - get $base_url/maven-metadata.xml $metadata - local resolved_version=`xmlstarlet sel -t -m '//snapshotVersion[extension[text()="zip"]]' -v value $metadata` - echo $resolved_version -} - -download_artifact() { - local file="$1"; shift - local url="$1"; shift - - echo "Downloading $url.md5" - get $url.md5 $file.md5 - local expected_md5="`cat $file.md5`" - - if [ -r $file ] - then - if [ "$expected_md5" == "`calculate_md5 $file`" ] - then - echo "Artifact already downloaded." - else - rm -f "$file" - fi - return 0 - fi - echo "Downloading artifact: $url" - get $url $file - - local actual_md5="`calculate_md5 $file`" - if [ "$expected_md5" == "$actual_md5" ] - then - echo "Artifact downloaded." - else - echo "Invalid checksum. Expected $expected_md5, got $actual_md5" >&2 - exit 1 - fi +usage() { + echo "usage: $0 -v <version> -f <file>" + exit 1 } -if [ $# -lt 2 ] +version= +file= + +while getopts "v:f:" opt +do + case $opt in + v) + version=$OPTARG + shift 2 + OPTIND=1 + ;; + f) + file=$OPTARG + shift 2 + OPTIND=1 + ;; + esac +done + +if [[ -z $version || -z $file || $# != 0 ]] then - method_install_usage + usage fi -case "$resolver" in - maven) - ;; - file) - if [ ! -r "$url" ] - then - echo "Could not read file: $url" >&2 - exit 1 - fi - - # TODO: should the zip file be copied into download/ so that - # there's always a local copy? - zip_file=$url - - if [ -z "$version" ] - then - version=`TZ=UTC date +"%Y%m%d-%H%M%S"` - fi - - resolved_version=$version - ;; - *) - method_install_usage "Invalid resolver type: $resolver" - ;; -esac - -if [ -d versions/$resolved_version ] +if [ -d versions/$version ] then - echo "Version $resolved_version is already installed" + echo "Version $version is already installed" exit 1 fi -mkdir -p versions/$resolved_version +mkdir -p versions/$version echo "Unpacking..." -unzip -q -d versions/$resolved_version $zip_file +unzip -q -d versions/$version $file -if [ ! -d versions/$resolved_version/root ] +if [ ! -d versions/$version/root ] then echo "Invalid zip file, did not contain a ./root directory." >&2 exit 1 fi -echo "Changing current symlink" -rm -f current -ln -s versions/$resolved_version/root current - +# TODO: This should go away if [ -d current/bin ] then ( @@ -137,38 +63,8 @@ then ) fi -( - cd versions/$resolved_version - if [ -d scripts ] - then - find scripts | xargs chmod +x - fi +app-run-hook -v "$version" -h pre-install - if [ -x scripts/postinstall ] - then - echo "Running postinstall..." - cd root - set +e - env -i \ - PATH=/bin:/usr/bin \ - APPSH_APPS=$apps \ - APPSH_HOME=$APPSH_HOME \ - APPSH_VERSION=$resolved_version \ - ../scripts/postinstall - set -e - ret=`echo $?` - if [ "$ret" != 0 ] - then - echo "Postinstall failed!" - exit 1 - fi - echo "Postinstall completed successfully" - fi -) +app-set-version -v "$version" -# if [ -r $apps/.app/var/list ] -# then -# sed "/^$name:$instance/d" $apps/.app/var/list > $apps/.app/var/list.new -# fi -# echo "$name:$instance:$version:$url" >> $apps/.app/var/list.new -# mv $apps/.app/var/list.new $apps/.app/var/list +app-run-hook -v "$version" -h post-install diff --git a/bin/pid-method b/libexec/app-method-pid index 29f6b4f..29f6b4f 100755 --- a/bin/pid-method +++ b/libexec/app-method-pid diff --git a/libexec/app-operate b/libexec/app-operate index 8e4ecac..007948c 100755 --- a/libexec/app-operate +++ b/libexec/app-operate @@ -8,43 +8,31 @@ APPSH_HOME=$(cd $(dirname "$0")/.. && pwd) . $APPSH_HOME/lib/common # HEADER END -method_operate() { - local name="$1"; shift - local instance="$1"; shift - local method="$1" - - if [ $# -gt 0 ] - then - shift - fi - - bin=`$APPSH_HOME/bin/app-cat-conf -f $apps/$name/$instance/current/etc/app.conf -g app -k method | cut -f 2 -d =` - - if [ -z "$bin" ] - then - bin=$APPSH_HOME/.app/lib/pid-method - fi - - if [ ! -x "$name/$instance/current/$bin" ] - then - echo "Invalid executable: $bin" >&2 - exit 1 - fi - - case "$method" in - start) run_app "$name" "$instance" "$bin" "start" "$@" ;; - stop) run_app "$name" "$instance" "$bin" "stop" "$@" ;; - status) run_app "$name" "$instance" "$bin" "status" "$@" ;; - restart) run_app "$name" "$instance" "$bin" "restart" "$@" ;; - run) run_app "$name" "$instance" "$bin" "run" "$@" ;; - *) - if [ -z "$method" ] - then - method_operate_usage - else - method_operate_usage "Unknown method $method" - fi - ;; - esac - exit $? -} +assert_is_app + +method="$1" + +bin=`app-conf get app.method` +bin=${bin-$APPSH_HOME/.app/libexec/app-method-pid} + +if [ ! -x "current/$bin" ] +then + echo "Invalid executable: $bin" >&2 + exit 1 +fi + +case "$method" in + start) run_app "$name" "$instance" "$bin" "start" "$@" ;; + stop) run_app "$name" "$instance" "$bin" "stop" "$@" ;; + status) run_app "$name" "$instance" "$bin" "status" "$@" ;; + restart) run_app "$name" "$instance" "$bin" "restart" "$@" ;; + run) run_app "$name" "$instance" "$bin" "run" "$@" ;; + *) + if [ -z "$method" ] + then + method_operate_usage + else + method_operate_usage "Unknown method $method" + fi + ;; +esac diff --git a/libexec/app-run-hook b/libexec/app-run-hook new file mode 100755 index 0000000..ec96c58 --- /dev/null +++ b/libexec/app-run-hook @@ -0,0 +1,49 @@ +#!/bin/bash + +set -e +set -u + +APPSH_HOME=$(cd $(dirname "$0")/.. && pwd) + +. $APPSH_HOME/lib/common +# HEADER END + +usage() { + echo "usage: $usage_app -v [version] -h [hook]" 2>&1 +} + +version= +hook= + +while getopts "v:h:" opt +do + case $opt in + v) + version=$OPTARG + shift 2 + OPTIND=1 + ;; + h) + hook=$OPTARG + shift 2 + OPTIND=1 + ;; + esac +done + +if [[ -z $version || -z $hook || $# != 0 ]] +then + usage +fi + +bin=versions/$version/hooks/$hook + +if [[ ! -r $bin ]] +then + exit 0 +fi + +# TODO: remove after +#chmod +x $bin +echo "Running hook: $hook" +run_app -v $version hooks/$hook diff --git a/libexec/app-set-version b/libexec/app-set-version new file mode 100755 index 0000000..75d44a8 --- /dev/null +++ b/libexec/app-set-version @@ -0,0 +1,50 @@ +#!/bin/bash + +set -e +set -u + +APPSH_HOME=$(cd $(dirname "$0")/.. && pwd) + +. $APPSH_HOME/lib/common +# HEADER END + +version= + +while getopts "v:" opt +do + case $opt in + v) + version=$OPTARG + shift 2 + OPTIND=1 + ;; + esac +done + +if [[ -z $version || $# != 0 ]] +then + usage +fi + +if [[ ! -d versions/$version ]] +then + fatal "Invalid version: not a directory: versions/$version" +fi + +if [[ -e current && ! -s current ]] +then + fatal "'current' is not a symlink" +fi + +if [[ -e current ]] +then + prev=`ls -l current` + prev=${prev/#* -> versions} + prev=${prev:1} + prev=${prev/%?root} + echo "Changing current symlink from $prev to $version" + ln -f -s versions/$version/root current +else + echo "Creating current symlink for version $version" + ln -s versions/$version/root current +fi diff --git a/test/app-init.bats b/test/app-init.bats index b62c42e..4e7c281 100755 --- a/test/app-init.bats +++ b/test/app-init.bats @@ -31,12 +31,15 @@ load utils fi app init -d my-app maven -r "file://$BATS_TMPDIR/repo" org.example:app-a:1.0-SNAPSHOT; echo_lines - eq '$status' 0 - eq '${lines[0]}' "Resolving version 1.0-SNAPSHOT..." + eq '$status' 0 + eq '${lines[0]}' "Resolving version 1.0-SNAPSHOT..." match '${lines[1]}' "Resolved version to 1.0-.*" match '${lines[2]}' "Downloading org.example:app-a:1.0-.*" - - eq '${#lines[*]}' 3 + eq '${lines[3]}' "Unpacking..." + match '${lines[4]}' "Creating current symlink for version 1.0-.*" + eq '${lines[5]}' "Running hook: post-install" + eq '${lines[6]}' "Post install" + eq '${#lines[*]}' 7 is_directory "my-app/.app" } diff --git a/test/data/app-a/hooks/post-install b/test/data/app-a/hooks/post-install new file mode 100755 index 0000000..99ad974 --- /dev/null +++ b/test/data/app-a/hooks/post-install @@ -0,0 +1,5 @@ +#!/bin/bash -e + +set -u + +echo "Post install" diff --git a/test/data/app-a/scripts/postinstall b/test/data/app-a/scripts/postinstall deleted file mode 100644 index dc176ff..0000000 --- a/test/data/app-a/scripts/postinstall +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -e - -echo "Hello World!" - -if [ -d etc/$APPSH_INSTANCE ] -then - find etc/$APPSH_INSTANCE -maxdepth 1 -type f | while read file - do - cp $file . - done -fi - -LOGS=$APPSH_APPS/$APPSH_NAME/$APPSH_INSTANCE/logs - -if [ ! -d $LOGS ] -then - echo "Creating logs directory" - mkdir $LOGS -fi - -ln -s $LOGS logs diff --git a/test/utils.bash b/test/utils.bash index fa2602e..3a9d425 100644 --- a/test/utils.bash +++ b/test/utils.bash @@ -7,6 +7,7 @@ exit_usage=1 exit_usage_wrong=0 setup() { + find test/data -name \*.zip | xargs rm -f PATH=/bin:/usr/bin PATH=$PATH:$APPSH_HOME APPSH_HOME=$(cd $BATS_TEST_DIRNAME/..; echo `pwd`) |