You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by be...@apache.org on 2014/02/15 10:50:05 UTC

[59/59] [abbrv] couchdb commit: updated refs/heads/1994-merge-rcouch to 6e59a78

remove node_package dependency


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/6e59a783
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/6e59a783
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/6e59a783

Branch: refs/heads/1994-merge-rcouch
Commit: 6e59a7834da941fee2e33941097f24f09ac493a0
Parents: 483dc97
Author: Benoit Chesneau <bc...@gmail.com>
Authored: Sat Feb 15 10:24:56 2014 +0100
Committer: Benoit Chesneau <bc...@gmail.com>
Committed: Sat Feb 15 10:24:56 2014 +0100

----------------------------------------------------------------------
 NOTICE                    |  42 ++++--
 rebar.config              |   4 -
 rel/files/app_epath.sh    | 173 ++++++++++++++++++++++
 rel/files/env.sh          | 229 +++++++++++++++++++++++++++++
 rel/files/erl             |  45 ++++++
 rel/files/nodetool        | 197 +++++++++++++++++++++++++
 rel/files/runner          | 319 +++++++++++++++++++++++++++++++++++++++++
 rel/reltool.config.script |  10 +-
 8 files changed, 999 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/6e59a783/NOTICE
----------------------------------------------------------------------
diff --git a/NOTICE b/NOTICE
index 60ec298..1a6139c 100644
--- a/NOTICE
+++ b/NOTICE
@@ -21,7 +21,7 @@ This product also includes the following third-party components:
  * jQuery (http://jquery.org/)
 
    Copyright 2012 jQuery Foundation and other contributors
- 
+
  * jQuery UI (http://jqueryui.com)
 
    Copyright 2011, Paul Bakaus
@@ -75,13 +75,13 @@ This product also includes the following third-party components:
   Copyright 2011, Jeremy Ashkenas
 
  * Sphinx (http://sphinx-doc.org/)
- 
+
    Copyright 2011, the Sphinx team
 
  * Sizzle (http://sizzlejs.com/)
- 
+
    Copyright 2010, The Dojo Foundation
- 
+
  * Underscore.js 1.4.2 (http://underscorejs.org)
 
    Copyright 2012, Jeremy Ashkenas
@@ -131,25 +131,25 @@ This product also includes the following third-party components:
    Copyright 2006-2013 (c) M. Alsup
 
  * couch_dbupdates
-   
+
    Copyright 2012, Benoît Chesneau <be...@refuge.io>
- 
+
  * mocha.js (https://github.com/visionmedia/mocha)
-  
+
    Copyright (c) 2011-2013 TJ Holowaychuk <tj...@vision-media.ca>
 
  * chaijs https://github.com/chaijs
-   
+
    Copyright (c) 2011-2013 Jake Luer jake@alogicalparadox.com
 
  * sinon-chai
 
    Copyright © 2012–2013 Domenic Denicola <do...@domenicdenicola.com>
- 
+
  * spin.js
 
    Copyright (c) 2011 Felix Gnass [fgnass at neteye dot de]
- 
+
  * font-awesome http://fortawesome.github.io/Font-Awesome/
 
    Copyright (c) 2013 Dave Gandy
@@ -188,4 +188,24 @@ This product also includes the following third-party components:
 
  * rebar https://github.com/rebar/rebar
 
-   Copyright (c) 2009 Dave Smith (dizzyd@dizzyd.com) 
+   Copyright (c) 2009 Dave Smith (dizzyd@dizzyd.com)
+
+ * rel/files/app_epath.sh https://github.com/basho/node_package
+
+   Copyright 2014 Basho - Apache License 2
+
+ * rel/files/env.sh https://github.com/basho/node_package
+
+   Copyright 2014 Basho - Apache License 2
+
+ * rel/files/erl https://github.com/basho/node_package
+
+   Copyright 2014 Basho - Apache License 2
+
+ * rel/files/nodetool https://github.com/basho/node_package
+
+   Copyright 2014 Basho - Apache License 2
+
+ * rel/files/runner https://github.com/basho/node_package
+
+   Copyright 2014 Basho - Apache License 2

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6e59a783/rebar.config
----------------------------------------------------------------------
diff --git a/rebar.config b/rebar.config
index a6959a3..a7a255c 100644
--- a/rebar.config
+++ b/rebar.config
@@ -9,10 +9,6 @@
 {require_otp_vsn, "R14B04|R15|R16"}.
 
 {deps, [
-    %% packaging
-    {node_package, ".*", {git, "git://github.com/basho/node_package",
-                         {tag, "1.3.8"}}},
-
     %% erlang oauth module
     {oauth, ".*",
      {git, "http://git-wip-us.apache.org/repos/asf/couchdb-oauth.git",

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6e59a783/rel/files/app_epath.sh
----------------------------------------------------------------------
diff --git a/rel/files/app_epath.sh b/rel/files/app_epath.sh
new file mode 100755
index 0000000..a3de910
--- /dev/null
+++ b/rel/files/app_epath.sh
@@ -0,0 +1,173 @@
+#!/bin/sh
+
+## ---------------------------------------------------------------------
+##
+## app_epath.sh: Parse Erlang app.config with POSIX tools for automation
+##
+## Copyright (c) 2013 Basho Technologies, Inc.  All Rights Reserved.
+##
+## This file is provided to you under the Apache License,
+## Version 2.0 (the "License"); you may not use this file
+## except in compliance with the License.  You may obtain
+## a copy of the License at
+##
+##   http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing,
+## software distributed under the License is distributed on an
+## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+## KIND, either express or implied.  See the License for the
+## specific language governing permissions and limitations
+## under the License.
+##
+## ---------------------------------------------------------------------
+
+## Example usage:
+#
+# #!/bin/sh
+#
+# # Load the functions
+# . path/to/app_epath.sh
+# 
+# # Build the path info
+# epaths=`make_app_epaths path/to/app.config`
+#
+# # View all of the settings. Quotes are important.
+# echo "$epaths"
+#
+# # Grep around in the paths for various items.
+# echo "$epaths" | grep 'riak_core ring_creation_size'
+# echo "$epaths" | grep "lager handlers lager_file_backend" | grep info
+#
+# # Use the epath function to get directly at settings
+# epath 'riak_core ring_creation_size' "$epaths"
+# epath 'riak_core platform_bin_dir' "$epaths"
+# epath 'riak_kv storage_backend' "$epaths"
+#
+# # Use epath to view all of the riak_core settings
+# epath riak_core
+#
+## End example
+
+## Here is a command you can put in your path for general cli use.
+# 
+# #!/bin/sh
+# 
+# # $1 quoted eterm path for search: 'riak_core ring_creation_size'
+# # $2 path/to/app.config
+# 
+# . path/to/app_epath.sh
+# 
+# epaths=`make_app_epaths "$2"`
+# epath "$1" "$epaths"
+#
+## End epath command
+
+# make_app_epaths takes a path to an app.config file as its argument and
+# and returns (prints) a flattened text structure of configuration settings.
+
+make_app_epaths () {
+    # Remove all lines containing comments
+    # Remove all blank lines
+    # Remove the first [
+    # Remove the last ].
+    # Remove all blank lines again (just in case)
+    appconfig=`cat $1 \
+                   | sed '/^[ \t]*%/d' \
+                   | sed '/^[ \t]*$/d' \
+                   | sed -e '/\[/{s///;:a' -e '$!N;$!ba' -e '}' \
+                   | sed '$ s/\]\.//g' \
+                   | sed '/^[ \t]*$/d'`
+
+    STACK=
+    INQUOTE=0
+    # The awk puts each char, spaces included, on their own line for parsing.
+    echo "$appconfig" | awk '{gsub(//,"\n");print}' | while read i; do
+        case "x${i}x" in
+            "x\"x")
+                # Flip the INQUOTE state and echo the quote
+                if [ 1 -eq $INQUOTE ]; then
+                    INQUOTE=0
+                else
+                    INQUOTE=1
+                fi
+                STACK="${STACK}${i}"
+                ;;
+            "xx")
+                if [ 1 -eq $INQUOTE ]; then
+                    # If in quotes, keep this space
+                    STACK="${STACK} "
+                fi
+                ;;
+            "x,x")
+                if [ 1 -eq $INQUOTE ]; then
+                    # If in quotes, keep this comma
+                    STACK="${STACK},"
+                else
+                    # Commas outside quotes means a new item is next
+                    STACK="${STACK} "
+                fi
+                ;;
+            "x{x")
+                if [ 1 -eq $INQUOTE ]; then
+                    # If in quotes, keep this bracket
+                    STACK="${STACK}{"
+                else
+                    # Add brace to the stack; will pop off from here on next }
+                    STACK="${STACK} __EBRACE__ "
+                fi
+                ;;
+            "x}x")
+                if [ 1 -eq $INQUOTE ]; then
+                    # If in quotes, keep this bracket
+                    STACK="${STACK}}"
+                else
+                    # We're only interested in printing leaves, not
+                    # intermediates like 'riak_core http', which contain lists.
+                    # See if the current stack ends with ] (end of list).
+                    echo $STACK | grep -E "__EBRACKET__$" >/dev/null 2>&1
+                    if [ 1 -eq $? ]; then
+                        # If not, print the stack without all of the mess.
+                        echo "$STACK" | \
+                            sed 's/ *__EBRACE__//g;s/ *__EBRACKET__//g;s/^ *//'
+                    fi
+                    # Pop off everything from the last brace on.
+                    STACK=`echo "$STACK" | sed 's/\(.*\) __EBRACE__.*/\1/g'`
+                fi
+                ;;
+            "x[x")
+                if [ 1 -eq $INQUOTE ]; then
+                    # If in quotes, keep this bracket
+                    STACK="${STACK}["
+                else
+                    # Add a placeholder to aid in determining whether or not to
+                    # print. That is, we don't want to print 'riak_core http'.
+                    STACK="${STACK} __EBRACKET__ "
+                fi
+                ;;
+            "x]x")
+                if [ 1 -eq $INQUOTE ]; then
+                    # If in quotes, keep this bracket
+                    STACK="${STACK}]"
+                fi
+                # Don't actually do anything with ], as the starting brackets
+                # are instead removed with }.
+                ;;
+            *)
+                # Anything else is just pushed.
+                STACK="${STACK}${i}"
+                ;;
+        esac
+    done
+}
+
+epath () {
+    # arg1   - a pattern to search for
+    # arg2   - output of make_app_epaths, passed in quoted
+    # output - search of arg2 for arg1, trimming arg1 from the beginning
+    #          Note: there may be multiple lines of output.
+    pat=$1
+    shift
+    echo "$*" | grep "$pat " | sed "s/^${pat} *//"
+}
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6e59a783/rel/files/env.sh
----------------------------------------------------------------------
diff --git a/rel/files/env.sh b/rel/files/env.sh
new file mode 100755
index 0000000..5a44a99
--- /dev/null
+++ b/rel/files/env.sh
@@ -0,0 +1,229 @@
+#!/bin/sh
+# -*- tab-width:4;indent-tabs-mode:nil -*-
+# ex: ts=4 sw=4 et
+
+# installed by node_package (github.com/basho/node_package)
+
+# /bin/sh on Solaris is not a POSIX compatible shell, but /usr/bin/ksh is.
+if [ `uname -s` = 'SunOS' -a "${POSIX_SHELL}" != "true" ]; then
+    POSIX_SHELL="true"
+    export POSIX_SHELL
+    # To support 'whoami' add /usr/ucb to path
+    PATH=/usr/ucb:$PATH
+    export PATH
+    exec /usr/bin/ksh $0 "$@"
+fi
+unset POSIX_SHELL # clear it so if we invoke other scripts, they run as ksh as well
+
+RUNNER_SCRIPT_DIR={{runner_script_dir}}
+RUNNER_SCRIPT=${0##*/}
+
+RUNNER_BASE_DIR={{runner_base_dir}}
+RUNNER_ETC_DIR={{runner_etc_dir}}
+RUNNER_LOG_DIR={{runner_log_dir}}
+RUNNER_LIB_DIR={{runner_lib_dir}}
+RUNNER_PATCH_DIR={{runner_patch_dir}}
+PIPE_DIR={{pipe_dir}}
+RUNNER_USER={{runner_user}}
+APP_VERSION={{app_version}}
+
+# Variables needed to support creation of .pid files
+# PID directory and pid file name of this app
+# ex: /var/run/riak & /var/run/riak/riak.pid
+RUN_DIR="/var/run" # for now hard coded unless we find a platform that differs
+PID_DIR=$RUN_DIR/$RUNNER_SCRIPT
+PID_FILE=$PID_DIR/$RUNNER_SCRIPT.pid
+
+# Threshold where users will be warned of low ulimit file settings
+# default it if it is not set
+ULIMIT_WARN={{runner_ulimit_warn}}
+if [ -z "$ULIMIT_WARN" ]; then
+    ULIMIT_WARN=4096
+fi
+
+# Registered process to wait for to consider start a success
+WAIT_FOR_PROCESS={{runner_wait_process}}
+
+WHOAMI=`whoami`
+
+# Echo to stderr on errors
+echoerr() { echo "$@" 1>&2; }
+
+# Extract the target node name from node.args
+NAME_ARG=`egrep '^\-s?name' $RUNNER_ETC_DIR/vm.args`
+if [ -z "$NAME_ARG" ]; then
+    echoerr "vm.args needs to have either -name or -sname parameter."
+    exit 1
+fi
+
+# Learn how to specify node name for connection from remote nodes
+echo "$NAME_ARG" | grep '^-sname' > /dev/null 2>&1
+if [ "X$?" = "X0" ]; then
+    NAME_PARAM="-sname"
+    NAME_HOST=""
+else
+    NAME_PARAM="-name"
+    echo "$NAME_ARG" | grep '@.*' > /dev/null 2>&1
+    if [ "X$?" = "X0" ]; then
+        NAME_HOST=`echo "${NAME_ARG}" | sed -e 's/.*\(@.*\)$/\1/'`
+    else
+        NAME_HOST=""
+    fi
+fi
+
+# Extract the target cookie
+COOKIE_ARG=`grep '^\-setcookie' $RUNNER_ETC_DIR/vm.args`
+if [ -z "$COOKIE_ARG" ]; then
+    echoerr "vm.args needs to have a -setcookie parameter."
+    exit 1
+fi
+
+# Parse out release and erts info
+START_ERL=`cat $RUNNER_BASE_DIR/releases/start_erl.data`
+ERTS_VSN=${START_ERL% *}
+APP_VSN=${START_ERL#* }
+
+# Add ERTS bin dir to our path
+ERTS_PATH=$RUNNER_BASE_DIR/erts-$ERTS_VSN/bin
+
+# Setup command to control the node
+NODETOOL="$ERTS_PATH/escript $ERTS_PATH/nodetool $NAME_ARG $COOKIE_ARG"
+NODETOOL_LITE="$ERTS_PATH/escript $ERTS_PATH/nodetool"
+
+# Ping node without stealing stdin
+ping_node() {
+    $NODETOOL ping < /dev/null
+}
+
+# Attempts to create a pid directory like /var/run/APPNAME and then
+# changes the permissions on that directory so the $RUNNER_USER can
+# read/write/delete .pid files during startup/shutdown
+create_pid_dir() {
+    # Validate RUNNER_USER is set and they have permissions to write to /var/run
+    # Don't continue if we've already sudo'd to RUNNER_USER
+    if ([ "$RUNNER_USER" ] && [ "x$WHOAMI" != "x$RUNNER_USER" ]); then
+        if [ -w $RUN_DIR ]; then
+            mkdir -p $PID_DIR
+            ES=$?
+            if [ "$ES" -ne 0 ]; then
+                return 1
+            else
+                # Change permissions on $PID_DIR
+                chown $RUNNER_USER $PID_DIR
+                ES=$?
+                if [ "$ES" -ne 0 ]; then
+                    return 1
+                else
+                    return 0
+                fi
+            fi
+        else
+            # If we don't have permissions, fail
+            return 1
+        fi
+    fi
+
+    # If RUNNER_USER is not set this is probably a test setup (devrel) and does
+    # not need a .pid file, so do not return error
+    return 0
+}
+
+# Attempt to create a pid file for the process
+# This function assumes the process is already up and running and can
+#    respond to a getpid call.  It also assumes that two processes
+#    with the same name will not be run on the machine
+# Do not print any error messages as failure to create a pid file because
+#    pid files are strictly optional
+# This function should really only be called in a "start" function
+#    you have been warned
+create_pid_file() {
+    # Validate a pid directory even exists
+    if [ -w $PID_DIR ]; then
+        # Grab the proper pid from getpid
+        get_pid
+        ES=$?
+        if [ "$ES" -ne 0 ]; then
+            return $ES
+        else
+            # Remove pid file if it already exists since we do not
+            # plan for multiple identical runners on a single machine
+            rm -f $PID_FILE
+            echo $PID > $PID_FILE
+            return 0
+        fi
+    else
+        return 1
+    fi
+}
+
+# Function to su into correct user
+check_user() {
+    # Validate that the user running the script is the owner of the
+    # RUN_DIR.
+    if ([ "$RUNNER_USER" ] && [ "x$WHOAMI" != "x$RUNNER_USER" ]); then
+        type sudo > /dev/null 2>&1
+        if [ "$?" -ne 0 ]; then
+            echoerr "sudo doesn't appear to be installed and your EUID isn't $RUNNER_USER" 1>&2
+            exit 1
+        fi
+        exec sudo -H -u $RUNNER_USER -i $RUNNER_SCRIPT_DIR/$RUNNER_SCRIPT $@
+    fi
+}
+
+# Function to validate the node is down
+node_down_check() {
+    MUTE=`ping_node 2> /dev/null`
+    if [ "$?" -eq 0 ]; then
+        echoerr "Node is already running!"
+        exit 1
+    fi
+}
+
+# Function to validate the node is up
+node_up_check() {
+    MUTE=`ping_node 2> /dev/null`
+    if [ "$?" -ne 0 ]; then
+        echoerr "Node is not running!"
+        exit 1
+    fi
+}
+
+# Function to check if the config file is valid
+check_config() {
+    MUTE=`$NODETOOL_LITE chkconfig $RUNNER_ETC_DIR/app.config`
+    if [ "$?" -ne 0 ]; then
+        echoerr "Error reading $RUNNER_ETC_DIR/app.config"
+        exit 1
+    fi
+    echo "config is OK"
+}
+
+# Function to check if ulimit is properly set
+check_ulimit() {
+
+    # don't fail if this is unset
+    if [ ! -z "$ULIMIT_WARN" ]; then
+        ULIMIT_F=`ulimit -n`
+        if [ "$ULIMIT_F" -lt $ULIMIT_WARN ]; then
+            echo "!!!!"
+            echo "!!!! WARNING: ulimit -n is ${ULIMIT_F}; ${ULIMIT_WARN} is the recommended minimum."
+            echo "!!!!"
+        fi
+    fi
+}
+
+# Set the PID global variable, return 1 on error
+get_pid() {
+    PID=`$NODETOOL getpid < /dev/null`
+    if [ "$?" -ne 0 ]; then
+        echo "Node is not running!"
+        return 1
+    fi
+
+    # don't allow empty or init pid's
+    if [ -z $PID ] || [ "$PID" -le 1 ]; then
+        return 1
+    fi
+
+    return 0
+}

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6e59a783/rel/files/erl
----------------------------------------------------------------------
diff --git a/rel/files/erl b/rel/files/erl
new file mode 100755
index 0000000..ec41a77
--- /dev/null
+++ b/rel/files/erl
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+# /bin/sh on Solaris is not a POSIX compatible shell, but /usr/bin/ksh is.
+if [ `uname -s` = 'SunOS' -a "${POSIX_SHELL}" != "true" ]; then
+    POSIX_SHELL="true"
+    export POSIX_SHELL
+    exec /usr/bin/ksh $0 "$@"
+fi
+unset POSIX_SHELL # clear it so if we invoke other scripts, they run as ksh as well
+
+
+## This script replaces the default "erl" in erts-VSN/bin. This is necessary
+## as escript depends on erl and in turn, erl depends on having access to a
+## bootscript (start.boot). Note that this script is ONLY invoked as a side-effect
+## of running escript -- the embedded node bypasses erl and uses erlexec directly
+## (as it should). 
+##
+## Note that this script makes the assumption that there is a start_clean.boot
+## file available in $ROOTDIR/release/VSN.
+
+## installed by node_package (github.com/basho/node_package)
+
+# Determine the abspath of where this script is executing from.
+ERTS_BIN_DIR=$(cd ${0%/*} && pwd)
+
+# Now determine the root directory -- this script runs from erts-VSN/bin,
+# so we simply need to strip off two dirs from the end of the ERTS_BIN_DIR
+# path.
+ROOTDIR=${ERTS_BIN_DIR%/*/*}
+
+# Parse out release and erts info
+START_ERL=`cat $ROOTDIR/releases/start_erl.data`
+ERTS_VSN=${START_ERL% *}
+APP_VSN=${START_ERL#* }
+
+BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin
+EMU=beam
+PROGNAME=`echo $0 | sed 's/.*\///'`
+CMD="$BINDIR/erlexec"
+export EMU
+export ROOTDIR
+export BINDIR
+export PROGNAME
+
+exec $CMD -boot $ROOTDIR/releases/$APP_VSN/start_clean ${1+"$@"}

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6e59a783/rel/files/nodetool
----------------------------------------------------------------------
diff --git a/rel/files/nodetool b/rel/files/nodetool
new file mode 100755
index 0000000..41b88e4
--- /dev/null
+++ b/rel/files/nodetool
@@ -0,0 +1,197 @@
+#!/usr/bin/env escript
+%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ft=erlang ts=4 sw=4 et
+%% -------------------------------------------------------------------
+%%
+%% nodetool: Helper Script for interacting with live nodes
+%%
+%% -------------------------------------------------------------------
+
+%% installed by node_package (github.com/basho/node_package)
+
+main(Args) ->
+    ok = start_epmd(),
+    %% Extract the args
+    {RestArgs, TargetNode} = process_args(Args, [], undefined),
+
+    %% Extract the RPC timeout from process dictionary, if it's defined
+    RpcTimeout = case erlang:get(rpctimeout) of
+                     undefined ->
+                         60000;
+                     Value ->
+                         Value
+                 end,
+
+    %% process_args() has side-effects (e.g. when processing "-name"),
+    %% so take care of app-starting business first.
+    [application:start(App) || App <- [crypto, public_key, ssl]],
+
+    %% any commands that don't need a running node
+    case RestArgs of
+        ["chkconfig", File] ->
+            case file:consult(File) of
+                {ok, _} ->
+                    io:format("ok\n"),
+                    halt(0);
+                {error, {Line, Mod, Term}} ->
+                    io:format(standard_error, 
+                              ["Error on line ", 
+                               file:format_error({Line, Mod, Term}), "\n"], []),
+                    halt(1);
+                {error, R} ->
+                    io:format(standard_error,
+                              ["Error reading config file: ", 
+                               file:format_error(R), "\n"], []),
+                    halt(1)
+            end;
+        _ ->
+            ok
+    end,
+
+    %% See if the node is currently running  -- if it's not, we'll bail
+    case {net_kernel:hidden_connect_node(TargetNode), net_adm:ping(TargetNode)} of
+        {true, pong} ->
+            ok;
+        {false, pong} ->
+            io:format(standard_error, "failed to connect to node ~p .\n", [TargetNode]),
+            halt(1);
+        {_, pang} ->
+            io:format(standard_error, "Node ~p not responding to pings.\n", [TargetNode]),
+            halt(1)
+    end,
+
+    case RestArgs of
+        ["getpid"] ->
+            io:format("~p\n", [list_to_integer(rpc:call(TargetNode, os, getpid, []))]);
+        ["ping"] ->
+            %% If we got this far, the node already responsed to a ping, so just dump
+            %% a "pong"
+            io:format("pong\n");
+        ["stop"] ->
+            io:format("~p\n", [rpc:call(TargetNode, init, stop, [], RpcTimeout)]);
+        ["restart"] ->
+            io:format("~p\n", [rpc:call(TargetNode, init, restart, [], RpcTimeout)]);
+        ["reboot"] ->
+            io:format("~p\n", [rpc:call(TargetNode, init, reboot, [], RpcTimeout)]);
+        ["rpc", Module, Function | RpcArgs] ->
+            case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function),
+                          [RpcArgs], RpcTimeout) of
+                ok ->
+                    ok;
+                {badrpc, Reason} ->
+                    io:format(standard_error, "RPC to ~p failed: ~p\n", [TargetNode, Reason]),
+                    halt(1);
+                _ ->
+                    halt(1)
+            end;
+        ["rpc_infinity", Module, Function | RpcArgs] ->
+            case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function), [RpcArgs], infinity) of
+                ok ->
+                    ok;
+                {badrpc, Reason} ->
+                    io:format(standard_error, "RPC to ~p failed: ~p\n", [TargetNode, Reason]),
+                    halt(1);
+                _ ->
+                    halt(1)
+            end;
+        ["rpcterms", Module, Function, ArgsAsString] ->
+            case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function),
+                          consult(ArgsAsString), RpcTimeout) of
+                {badrpc, Reason} ->
+                    io:format(standard_error, "RPC to ~p failed: ~p\n", [TargetNode, Reason]),
+                    halt(1);
+                Other ->
+                    io:format("~p\n", [Other])
+            end;
+        Other ->
+            io:format("Other: ~p\n", [Other]),
+            io:format("Usage: nodetool {ping|stop|restart|reboot|chkconfig}\n")
+    end,
+    net_kernel:stop().
+
+process_args([], Acc, TargetNode) ->
+    {lists:reverse(Acc), TargetNode};
+process_args(["-setcookie", Cookie | Rest], Acc, TargetNode) ->
+    erlang:set_cookie(node(), list_to_atom(Cookie)),
+    process_args(Rest, Acc, TargetNode);
+process_args(["-name", TargetName | Rest], Acc, _) ->
+    ThisNode = append_node_suffix(TargetName, "_maint_"),
+    {ok, _} = net_kernel:start([ThisNode, longnames]),
+    process_args(Rest, Acc, nodename(TargetName));
+process_args(["-sname", TargetName | Rest], Acc, _) ->
+    ThisNode = append_node_suffix(TargetName, "_maint_"),
+    {ok, _} = net_kernel:start([ThisNode, shortnames]),
+    process_args(Rest, Acc, nodename(TargetName));
+process_args(["-rpctimeout", TimeoutStr | Rest], Acc, TargetNode) ->
+    Timeout = case TimeoutStr of
+                  "infinity" -> infinity;
+                  _          -> list_to_integer(TimeoutStr)
+              end,
+    erlang:put(rpctimeout, Timeout),
+    process_args(Rest, Acc, TargetNode);
+process_args([Arg | Rest], Acc, Opts) ->
+    process_args(Rest, [Arg | Acc], Opts).
+
+
+start_epmd() ->
+    [] = os:cmd(epmd_path() ++ " -daemon"),
+    ok.
+
+epmd_path() ->
+    ErtsBinDir = filename:dirname(escript:script_name()),
+    Name = "epmd",
+    case os:find_executable(Name, ErtsBinDir) of
+        false ->
+            case os:find_executable(Name) of
+                false ->
+                    io:format("Could not find epmd.~n"),
+                    halt(1);
+                GlobalEpmd ->
+                    GlobalEpmd
+            end;
+        Epmd ->
+            Epmd
+    end.
+
+
+nodename(Name) ->
+    case string:tokens(Name, "@") of
+        [_Node, _Host] ->
+            list_to_atom(Name);
+        [Node] ->
+            [_, Host] = string:tokens(atom_to_list(node()), "@"),
+            list_to_atom(lists:concat([Node, "@", Host]))
+    end.
+
+append_node_suffix(Name, Suffix) ->
+    case string:tokens(Name, "@") of
+        [Node, Host] ->
+            list_to_atom(lists:concat([Node, Suffix, os:getpid(), "@", Host]));
+        [Node] ->
+            list_to_atom(lists:concat([Node, Suffix, os:getpid()]))
+    end.
+
+
+%%
+%% Given a string or binary, parse it into a list of terms, ala file:consult/0
+%%
+consult(Str) when is_list(Str) ->
+    consult([], Str, []);
+consult(Bin) when is_binary(Bin)->
+    consult([], binary_to_list(Bin), []).
+
+consult(Cont, Str, Acc) ->
+    case erl_scan:tokens(Cont, Str, 0) of
+        {done, Result, Remaining} ->
+            case Result of
+                {ok, Tokens, _} ->
+                    {ok, Term} = erl_parse:parse_term(Tokens),
+                    consult([], Remaining, [Term | Acc]);
+                {eof, _Other} ->
+                    lists:reverse(Acc);
+                {error, Info, _} ->
+                    {error, Info}
+            end;
+        {more, Cont1} ->
+            consult(Cont1, eof, Acc)
+    end.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6e59a783/rel/files/runner
----------------------------------------------------------------------
diff --git a/rel/files/runner b/rel/files/runner
new file mode 100755
index 0000000..ffad13f
--- /dev/null
+++ b/rel/files/runner
@@ -0,0 +1,319 @@
+#!/bin/sh
+# -*- tab-width:4;indent-tabs-mode:nil -*-
+# ex: ts=4 sw=4 et
+
+# installed by node_package (github.com/basho/node_package)
+
+# Pull environment for this install
+. "{{runner_base_dir}}/lib/env.sh"
+
+
+# Keep track of where script was invoked
+ORIGINAL_DIR=$(pwd)
+
+# Make sure CWD is set to runner run dir
+cd $RUNNER_BASE_DIR
+
+# Identify the script name
+SCRIPT=`basename $0`
+
+usage() {
+    echo "Usage: $SCRIPT {start | stop| restart | reboot | ping | console | attach | "
+    echo "                    attach-direct | ertspath | chkconfig | escript | version | "
+    echo "                    getpid | top [-interval N] [-sort reductions|memory|msg_q] [-lines N] }"
+}
+
+# All commands must either call bootstrap or bootstrapd
+# Call bootstrap for non-daemon commands like ping or chkconfig
+# Call bootstrapd for daemon commands like start/stop/console
+bootstrap() {
+    # Make sure the user running this script is the owner and/or su to that user
+    check_user $@
+    ES=$?
+    if [ "$ES" -ne 0 ]; then
+        exit $ES
+    fi
+}
+
+bootstrapd() {
+    # Create PID directory if it does not exist before dropping permissiongs
+    # to the runner user
+    create_pid_dir
+    ES=$?
+    if [ "$ES" -ne 0 ]; then
+        echoerr "Unable to access $PID_DIR, permission denied, run script as root"
+        exit 1
+    fi
+
+    # Now call bootstrap to drop to $RUNNER_USER
+    bootstrap $@
+}
+
+# Check the first argument for instructions
+case "$1" in
+    start)
+        # Bootstrap daemon command (check perms & drop to $RUNNER_USER)
+        bootstrapd $@
+
+        # Make sure there is not already a node running
+        node_down_check
+
+        # Sanity check the app.config file
+        check_config > /dev/null
+        ES=$?
+        if [ "$ES" -ne 0 ]; then
+            exit $ES
+        fi
+
+        # Warn the user if ulimit is too low
+        check_ulimit
+
+        # Make sure log directory exists
+        mkdir -p $RUNNER_LOG_DIR
+
+        HEART_COMMAND="$RUNNER_SCRIPT_DIR/$RUNNER_SCRIPT start"
+        export HEART_COMMAND
+        mkdir -p $PIPE_DIR
+        $ERTS_PATH/run_erl -daemon $PIPE_DIR/ $RUNNER_LOG_DIR \
+            "exec $RUNNER_SCRIPT_DIR/$RUNNER_SCRIPT console" 2>&1
+
+        if [ ! -z "$WAIT_FOR_PROCESS" ]; then
+            # Wait for the node to come up. We can't just ping it because
+            # distributed erlang comes up for a second before the node crashes
+            # (eg. in the case of an unwriteable disk). Once the node comes
+            # up we check for the $WAIT_FOR_PROCESS} process. If that's running
+            # then we assume things are good enough. This will at least let
+            # the user know when the node is crashing right after startup.
+            WAIT=${WAIT_FOR_ERLANG:-15}
+            while [ $WAIT -gt 0 ]; do
+                WAIT=`expr $WAIT - 1`
+                sleep 1
+
+                # squash stderr output to not frighten users if the node does not
+                # come up right away
+                MUTE=`ping_node 2> /dev/null`
+                if [ "$?" -ne 0 ]; then
+                    continue
+                fi
+                PROCESS=`$NODETOOL rpcterms erlang whereis "'${WAIT_FOR_PROCESS}'."`
+                if [ "$PROCESS" != "undefined" ]; then
+                    # Attempt to create a .pid file for the process
+                    create_pid_file
+                    exit 0
+                fi
+            done
+            echo "${SCRIPT} failed to start within ${WAIT_FOR_ERLANG:-15} seconds,"
+            echo "see the output of '${SCRIPT} console' for more information."
+            echo "If you want to wait longer, set the environment variable"
+            echo "WAIT_FOR_ERLANG to the number of seconds to wait."
+            exit 1
+        fi
+
+        # Attempt to create .pid file
+        create_pid_file
+        ;;
+
+    stop)
+        # Bootstrap daemon command (check perms & drop to $RUNNER_USER)
+        bootstrapd $@
+
+        get_pid
+        ES=$?
+        if [ "$ES" -ne 0 ] || [ -z $PID ]; then
+            exit $ES
+        fi
+
+        # Tell nodetool to stop
+        $NODETOOL stop
+        ES=$?
+        if [ "$ES" -ne 0 ]; then
+            exit $ES
+        fi
+
+        # Now wait for the app to *really* stop
+        while `kill -s 0 $PID 2>/dev/null`;
+        do
+            sleep 1
+        done
+
+        # remove pid file
+        rm -f $PID_FILE
+        ;;
+
+    restart)
+        # Bootstrap daemon command (check perms & drop to $RUNNER_USER)
+        bootstrapd $@
+
+        ## Restart the VM without exiting the process
+        $NODETOOL restart
+        ES=$?
+        if [ "$ES" -ne 0 ]; then
+            exit $ES
+        fi
+        ;;
+
+    reboot)
+        # Bootstrap daemon command (check perms & drop to $RUNNER_USER)
+        bootstrapd $@
+
+        ## Restart the VM completely (uses heart to restart it)
+        $NODETOOL reboot
+        ES=$?
+        if [ "$ES" -ne 0 ]; then
+            exit $ES
+        fi
+        ;;
+
+    ping)
+        # Bootstrap command (simply drop to $RUNNER_USER)
+        bootstrap $@
+
+        ## See if the VM is alive
+        ping_node
+        ES=$?
+        if [ "$ES" -ne 0 ]; then
+            exit $ES
+        fi
+        ;;
+
+    attach-direct)
+        # Bootstrap daemon command (check perms & drop to $RUNNER_USER)
+        bootstrapd $@
+
+        # Allow attaching to a node without pinging it
+        if [ "$2" = "-f" ]; then
+          echo "Forcing connection..."
+        else
+          # Make sure a node is running
+          node_up_check
+        fi
+
+        echo "Direct Shell: Use \"Ctrl-D\" to quit. \"Ctrl-C\" will terminate the $SCRIPT node."
+        shift
+        exec $ERTS_PATH/to_erl $PIPE_DIR
+        ;;
+
+    attach)
+        # Bootstrap daemon command (check perms & drop to $RUNNER_USER)
+        bootstrapd $@
+
+        # Make sure a node is running
+        node_up_check
+
+        echo "Remote Shell: Use \"Ctrl-C a\" to quit. q() or init:stop() will terminate the $SCRIPT node."
+        shift
+        NODE_NAME=${NAME_ARG#* }
+        exec $ERTS_PATH/erl -name c_$$_$NODE_NAME -hidden -remsh $NODE_NAME $COOKIE_ARG
+        ;;
+
+    console)
+        # Bootstrap daemon command (check perms & drop to $RUNNER_USER)
+        bootstrapd $@
+
+        RES=`ping_node`
+        if [ "$?" -eq 0 ]; then
+            echo "Node is already running - use '$SCRIPT attach' instead"
+            exit 1
+        fi
+
+        # Sanity check the app.config file
+        check_config
+        ES=$?
+        if [ "$ES" -ne 0 ]; then
+            exit $ES
+        fi
+
+        # Warn the user if ulimit -n is less than the defined threshold
+        check_ulimit
+
+        # Make sure log directory exists
+        mkdir -p $RUNNER_LOG_DIR
+
+        # Setup beam-required vars
+        ROOTDIR=$RUNNER_BASE_DIR
+        BINDIR=$RUNNER_BASE_DIR/erts-$ERTS_VSN/bin
+        EMU=beam
+        PROGNAME=`echo $0 | sed 's/.*\///'`
+        CMD="$BINDIR/erlexec -boot $RUNNER_BASE_DIR/releases/$APP_VSN/$RUNNER_SCRIPT \
+             -config $RUNNER_ETC_DIR/app.config \
+            -pa $RUNNER_PATCH_DIR \
+            -args_file $RUNNER_ETC_DIR/vm.args -- ${1+"$@"}"
+        export EMU
+        export ROOTDIR
+        export BINDIR
+        export PROGNAME
+
+        # Dump environment info for logging purposes
+        echo "Exec: $CMD"
+        echo "Root: $ROOTDIR"
+
+        # Log the startup
+        logger -t "$SCRIPT[$$]" "Starting up"
+
+        # Start the VM
+        exec $CMD
+        ;;
+
+    top)
+        # Bootstrap command (simply drop to $RUNNER_USER)
+        bootstrap $@
+
+        # Make sure the local node IS running
+        node_up_check
+
+        shift
+        MYPID=$$
+        NODE_NAME=${NAME_ARG#* }
+        $ERTS_PATH/erl -noshell -noinput \
+            -pa $RUNNER_PATCH_DIR \
+            -hidden $NAME_PARAM np_etop$MYPID$NAME_HOST $COOKIE_ARG \
+            -s etop -s erlang halt -output text \
+            -node $NODE_NAME \
+            $* -tracing off
+        ;;
+
+    ertspath)
+        echo $ERTS_PATH
+        ;;
+
+    chkconfig)
+        # Bootstrap command (simply drop to $RUNNER_USER)
+        bootstrap $@
+
+        check_config
+        ;;
+
+    escript)
+        # Bootstrap command (simply drop to $RUNNER_USER)
+        bootstrap $@
+
+        shift
+        $ERTS_PATH/escript "$@"
+        ES=$?
+        if [ "$ES" -ne 0 ]; then
+            exit $ES
+        fi
+        ;;
+
+    version)
+        echo $APP_VERSION
+        ;;
+
+    getpid)
+        # Bootstrap command (simply drop to $RUNNER_USER)
+        bootstrap $@
+
+        # Get the PID from nodetool
+        get_pid
+        ES=$?
+        if [ "$ES" -ne 0 ] || [ -z $PID ]; then
+            exit $ES
+        fi
+        echo $PID
+        ;;
+    *)
+        usage
+        ;;
+esac
+
+exit 0

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6e59a783/rel/reltool.config.script
----------------------------------------------------------------------
diff --git a/rel/reltool.config.script b/rel/reltool.config.script
index 60e3a37..19b40a5 100644
--- a/rel/reltool.config.script
+++ b/rel/reltool.config.script
@@ -127,11 +127,11 @@ CouchJSName = proplists:get_value(couchjs_name, Cfg, "couchjs"),
         {copy, "../etc/couchdb/empty", "data/KEEP"},
 
         %% Copy base files for starting and interacting w/ node
-        {copy, "../src/node_package/priv/base/erl", "{{erts_vsn}}/bin/erl"},
-        {copy, "../src/node_package/priv/base/nodetool", "{{erts_vsn}}/bin/nodetool"},
-        {template, "../src/node_package/priv/base/runner", "bin/couchdb"},
-        {template, "../src/node_package/priv/base/env.sh", "lib/env.sh"},
-        {template, "../src/node_package/priv/base/app_epath.sh", "lib/app_epath.sh"},
+        {copy, "files/erl", "{{erts_vsn}}/bin/erl"},
+        {copy, "files/nodetool", "{{erts_vsn}}/bin/nodetool"},
+        {template, "files/runner", "bin/couchdb"},
+        {template, "files/env.sh", "lib/env.sh"},
+        {template, "files/app_epath.sh", "lib/app_epath.sh"},
 
         %% config files
         {template, "../etc/couchdb/app.config", "etc/app.config"},