This is an automated email from the ASF dual-hosted git repository.

jan pushed a commit to branch feat/conf
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 082c7164598819f757b87f976e4e762db427c508
Author: Jan Lehnardt <[email protected]>
AuthorDate: Fri Sep 14 10:42:02 2018 +0200

    feat: move [native_]query_server & os_daemons setup out of runtime config
    
    CouchDB ships with two default query_servers (javascript and coffeescript)
    as well as one default native_query_server (query aka mango). These used
    to be configured in default.ini in these sections:
    
    ```
    [query_servers]
    javascript = {{prefix}}/bin/couchjs {{prefix}}/share/server/main.js
    coffeescript = {{prefix}}/bin/couchjs {{prefix}}/share/server/main-coffee.js
    
    ; enable mango query engine
    [native_query_servers]
    query = {mango_native_proc, start_link, []}
    ; erlang query server
    ; erlang = {couch_native_process, start_link, []}
    ```
    
    This allowed end-users post-install and even runtime-changes to which
    query servers are enabled and where their binaries live.
    
    This patch changes things, so only a post-install, but not at-runtime
    changes are possible from now on.
    
    This still allows people to configure their CouchDB to run a third-
    party query server like the somewhat popular Python query server,
    but it changes the way the setup is done.
    
    Query Servers
    
    The javascript and coffeescript query servers continue to be enabled
    by default. Setup differences have been moved from default.ini to
    the couchdb and couchdb.cmd start scripts respectively.
    
    Additional query servers can now be configured using environment
    variables:
    
    ```
    export COUCHDB_QUERY_SERVER_PYTHON="/path/to/python/query/server.py with 
args"
    couchdb
    ```
    
    Where the last segment in the environment variable matches the usual
    lowercase(!) query language in the design doc `language` field.
    
    Multiple query servers can be configured by using more environment
    variables.
    
    Native Query Servers
    
    The mango query server continues to be enabled by default. The erlang
    query server continues to be disabled by default. This patch adds
    a `[native_query_servers] enable_erlang_query_server = BOOL` setting
    (defaults to `"false"`) to enable the erlang query server.
    
    If the legacy configuration for enabling the query server is detected,
    that is counted as a `true` setting as well, so existing configurations
    continue to work just fine.
    
    Windows
    
    Since the setting of the `./configure` time `PREFIX` happens during
    `make release`, I had to adapt the `couchdb` and `couchdb.cmd` scripts
    to have the correct env vars set and the `PREFIX` replaced there.
    
    I did this to the best of my abilities and research, but this needs
    review from the Windows team (Hi Joan! :).
    
    OS Daemons
    
    Although deprecated in 2.2.0, we’re keeping support for this until 3.x,
    but the configuration changes analogous to query servers.
    
    Previously, configuration looked like this:
    
    ```
    [os_daemons]
    name = /path/to/daemon with args
    ```
    
    With this patch, setup looks like this:
    
    ```
    COUCHDB_OS_DAEMON_NAME="/path/to/daemon with args"
    couchdb
    ```
    
    Multiple OS Daemons can be started with multiple env vars. The final
    segment in the env var becomes the daemon identifier inside CouchDB
    as lowercase(!).
---
 dev/run                                            | 24 +++++-----
 .../bin/couchdb.cmd => files/couchdb.cmd.in}       |  3 ++
 rel/{overlay/bin/couchdb => files/couchdb.in}      |  4 +-
 rel/overlay/etc/default.ini                        |  8 +---
 rel/reltool.config                                 |  4 +-
 src/couch/src/couch_os_daemons.erl                 | 21 ++++++---
 src/couch/src/couch_proc_manager.erl               | 52 +++++++++++++++++++++-
 7 files changed, 91 insertions(+), 25 deletions(-)

diff --git a/dev/run b/dev/run
index a5d8fde..c31bde1 100755
--- a/dev/run
+++ b/dev/run
@@ -270,16 +270,6 @@ def boot_haproxy(ctx):
 
 
 def hack_default_ini(ctx, node, contents):
-    # Replace couchjs command
-    couchjs = os.path.join(ctx['rootdir'], "src", "couch", "priv", "couchjs")
-    mainjs = os.path.join(ctx['rootdir'], "share", "server", "main.js")
-    coffeejs = os.path.join(ctx['rootdir'], "share", "server", 
"main-coffee.js")
-
-    repl = toposixpath("javascript = %s %s" % (couchjs, mainjs))
-    contents = re.sub("(?m)^javascript.*$", repl, contents)
-
-    repl = toposixpath("coffeescript = %s %s" % (couchjs, coffeejs))
-    contents = re.sub("(?m)^coffeescript.*$", repl, contents)
 
     if ctx['enable_erlang_views']:
         contents = re.sub(
@@ -410,15 +400,29 @@ def check_node_alive(url):
     if error is not None:
         raise error
 
+def set_boot_env(ctx):
+
+    # fudge default query server paths
+    couchjs = os.path.join(ctx['rootdir'], "src", "couch", "priv", "couchjs")
+    mainjs = os.path.join(ctx['rootdir'], "share", "server", "main.js")
+    coffeejs = os.path.join(ctx['rootdir'], "share", "server", 
"main-coffee.js")
+
+    qs_javascript = toposixpath("%s %s" % (couchjs, mainjs))
+    qs_coffescript = toposixpath("%s %s" % (couchjs, coffeejs))
+
+    os.environ['COUCHDB_QUERY_SERVER_JAVASCRIPT'] = qs_javascript
+    os.environ['COUCHDB_QUERY_SERVER_COFFEESCRIPT'] = qs_coffescript
 
 @log('Start node {node}')
 def boot_node(ctx, node):
     erl_libs = os.path.join(ctx['rootdir'], "src")
+    set_boot_env(ctx)
     env = os.environ.copy()
     env["ERL_LIBS"] = os.pathsep.join([erl_libs])
 
     node_etcdir = os.path.join(ctx['devdir'], "lib", node, "etc")
     reldir = os.path.join(ctx['rootdir'], "rel")
+
     cmd = [
         "erl",
         "-args_file", os.path.join(node_etcdir, "vm.args"),
diff --git a/rel/overlay/bin/couchdb.cmd b/rel/files/couchdb.cmd.in
similarity index 84%
rename from rel/overlay/bin/couchdb.cmd
rename to rel/files/couchdb.cmd.in
index 5e5f2cf..9438872 100644
--- a/rel/overlay/bin/couchdb.cmd
+++ b/rel/files/couchdb.cmd.in
@@ -25,6 +25,9 @@ set EMU=beam
 set PROGNAME=%~n0
 set PATH=%PATH%;%COUCHDB_BIN_DIR%
 
+set COUCHDB_QUERY_SERVER_JAVASCRIPT="{{prefix}}/bin/couchjs 
{{prefix}}/share/server/main.js"
+set COUCHDB_QUERY_SERVER_COFFEESCRIPT="{{prefix}}/bin/couchjs 
{{prefix}}/share/server/main-coffee.js"
+
 "%BINDIR%\erl" -boot "%ROOTDIR%\releases\%APP_VSN%\couchdb" ^
 -args_file "%ROOTDIR%\etc\vm.args" ^
 -config "%ROOTDIR%\releases\%APP_VSN%\sys.config" %*
diff --git a/rel/overlay/bin/couchdb b/rel/files/couchdb.in
similarity index 85%
rename from rel/overlay/bin/couchdb
rename to rel/files/couchdb.in
index a9e6e9b..aae179a 100755
--- a/rel/overlay/bin/couchdb
+++ b/rel/files/couchdb.in
@@ -26,10 +26,12 @@ export BINDIR="$ROOTDIR/erts-$ERTS_VSN/bin"
 export EMU=beam
 export PROGNAME=`echo $0 | sed 's/.*\///'`
 
+export COUCHDB_QUERY_SERVER_JAVASCRIPT="{{prefix}}/bin/couchjs 
{{prefix}}/share/server/main.js"
+export COUCHDB_QUERY_SERVER_COFFEESCRIPT="{{prefix}}/bin/couchjs 
{{prefix}}/share/server/main-coffee.js"
+
 ARGS_FILE="${COUCHDB_ARGS_FILE:-$ROOTDIR/etc/vm.args}"
 
SYSCONFIG_FILE="${COUCHDB_SYSCONFIG_FILE:-$ROOTDIR/releases/$APP_VSN/sys.config}"
 
 exec "$BINDIR/erlexec" -boot "$ROOTDIR/releases/$APP_VSN/couchdb" \
      -args_file "${ARGS_FILE}" \
      -config "${SYSCONFIG_FILE}" "$@"
-
diff --git a/rel/overlay/etc/default.ini b/rel/overlay/etc/default.ini
index ef670d1..4570814 100644
--- a/rel/overlay/etc/default.ini
+++ b/rel/overlay/etc/default.ini
@@ -260,13 +260,9 @@ credentials = false
 ; List of hosts separated by a comma. * means accept all
 ; hosts =
 
-[query_servers]
-javascript = {{prefix}}/bin/couchjs {{prefix}}/share/server/main.js
-coffeescript = {{prefix}}/bin/couchjs {{prefix}}/share/server/main-coffee.js
-
-; enable mango query engine
 [native_query_servers]
-query = {mango_native_proc, start_link, []}
+; erlang query server
+; enable_erlang_query_server = false
 
 ; Changing reduce_limit to false will disable reduce_limit.
 ; If you think you're hitting reduce_limit with a "good" reduce function,
diff --git a/rel/reltool.config b/rel/reltool.config
index 2c55d09..bf4ae44 100644
--- a/rel/reltool.config
+++ b/rel/reltool.config
@@ -125,5 +125,7 @@
     {copy, "files/sys.config", "releases/\{\{rel_vsn\}\}/sys.config"},
     {copy, "files/vm.args", "releases/\{\{rel_vsn\}\}/vm.args"},
     {template, "overlay/etc/default.ini", "etc/default.ini"},
-    {template, "overlay/etc/vm.args", "etc/vm.args"}
+    {template, "overlay/etc/vm.args", "etc/vm.args"},
+    {template, "files/couchdb.in", "bin/couchdb"},
+    {template, "files/couchdb.cmd.in", "bin/couchdb.cmd"}
 ]}.
diff --git a/src/couch/src/couch_os_daemons.erl 
b/src/couch/src/couch_os_daemons.erl
index cd019db..2427d67 100644
--- a/src/couch/src/couch_os_daemons.erl
+++ b/src/couch/src/couch_os_daemons.erl
@@ -72,10 +72,6 @@ handle_call(Msg, From, Table) ->
 
 handle_cast({config_change, Sect, Key}, Table) ->
     restart_daemons(Table, Sect, Key),
-    case Sect of
-        "os_daemons" -> reload_daemons(Table);
-        _ -> ok
-    end,
     {noreply, Table};
 handle_cast(stop, Table) ->
     {stop, normal, Table};
@@ -288,9 +284,24 @@ handle_log_message(Name, Msg, Level) ->
 % Daemon management helpers
 %
 
+get_daemons() ->
+    % map all COUCHDB_OS_DAEMON_* vars out of os:getenv
+    lists:filtermap(fun(Var) ->
+        case string:split(Var, "=") of
+            [VarName, Cmd] ->
+                case string:find(VarName, "COUCHDB_OS_DAEMON_") of
+                    nomatch ->
+                        false;
+                    "COUCHDB_OS_DAEMON_" ++ Name ->
+                        {true, {string:lowercase(Name), Cmd}}
+                end;
+            _Else -> false
+        end
+    end, os:getenv()).
+
 reload_daemons(Table) ->
     % List of daemons we want to have running.
-    Configured = lists:sort(config:get("os_daemons")),
+    Configured = lists:sort(get_daemons()),
     
     % Remove records for daemons that were halted.
     MSpecHalted = #daemon{name='$1', cmd='$2', status=halted, _='_'},
diff --git a/src/couch/src/couch_proc_manager.erl 
b/src/couch/src/couch_proc_manager.erl
index 04101f2..b663928 100644
--- a/src/couch/src/couch_proc_manager.erl
+++ b/src/couch/src/couch_proc_manager.erl
@@ -372,12 +372,60 @@ new_proc(Client) ->
     end,
     exit(Resp).
 
+get_env_for_spec(Spec, Target) ->
+    % loop over os:getenv(), match SPEC_TARGET
+    lists:filtermap(fun(VarName) ->
+        SpecStr = Spec ++ Target,
+        case string:split(VarName, "=") of
+            [SpecStr, Cmd] -> {true, Cmd};
+            _Else -> false
+        end
+    end, os:getenv()).
+
+get_query_server(LangStr) ->
+    % look for COUCH_QUERY_SERVER_LANGSTR in env
+    % if exists, return value, else undefined
+    UpperLangString = string:uppercase(LangStr),
+    case get_env_for_spec("COUCHDB_QUERY_SERVER_", UpperLangString) of
+        [] -> undefined;
+        [Command] -> Command
+    end.
+
+native_query_server_enabled() ->
+    % 1. [native_query_server] enable_erlang_query_server = true | false
+    % 2. if [native_query_server] erlang == {couch_native_process, start_link, 
[]} -> pretend true as well
+    NativeEnabled = config:get_boolean("native_query_server", 
"enable_erlang_query_server", false),
+    NativeLegacyConfig = config:get("native_query_server", "erlang", ""),
+    NativeLegacyEnabled = NativeLegacyConfig =:= "{couch_native_process, 
start_link, []}",
+
+    % there surely is a more elegant way to do this that eludes me at present
+    case {NativeEnabled, NativeLegacyEnabled} of
+        {true, true} -> true;
+        {true, _} -> true;
+        {_, true} -> true;
+        _ -> false
+    end.
+
+get_native_query_server("query") -> % mango query server
+    "{mango_native_proc, start_link, []}";
+get_native_query_server("erlang") -> % erlang query server
+    case native_query_server_enabled() of
+        true -> "{couch_native_process, start_link, []}";
+        _Else -> undefined
+    end;
+get_native_query_server(LangStr) ->
+    % same as above, but COUCH_NATIVE_QUERY_SERVER_LANGSTR
+    UpperLangString = string:uppercase(LangStr),
+    case get_env_for_spec("COUCHDB_NATIVE_QUERY_SERVER_", UpperLangString) of
+        [] -> undefined;
+        [Command] -> Command
+    end.
 
 new_proc_int(From, Lang) when is_binary(Lang) ->
     LangStr = binary_to_list(Lang),
-    case config:get("query_servers", LangStr) of
+    case get_query_server(LangStr) of
     undefined ->
-        case config:get("native_query_servers", LangStr) of
+        case get_native_query_server(LangStr) of
         undefined ->
             gen_server:reply(From, {unknown_query_language, Lang});
         SpecStr ->

Reply via email to