summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Lehnardt <jan@apache.org>2018-09-14 10:42:02 +0200
committerJan Lehnardt <jan@apache.org>2018-11-09 14:51:33 +0100
commit36e2323044dee3cadf5f766462000d7be89fc4dc (patch)
tree431f999dcd9a7739d003c8d00a3c9708f9115836
parent21368b7449bd9276b5450838f13758de342e9df6 (diff)
downloadcouchdb-36e2323044dee3cadf5f766462000d7be89fc4dc.tar.gz
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(!).
-rwxr-xr-xdev/run24
-rw-r--r--rel/files/couchdb.cmd.in (renamed from rel/overlay/bin/couchdb.cmd)3
-rwxr-xr-xrel/files/couchdb.in (renamed from rel/overlay/bin/couchdb)4
-rw-r--r--rel/overlay/etc/default.ini8
-rw-r--r--rel/reltool.config4
-rw-r--r--src/couch/src/couch_os_daemons.erl21
-rw-r--r--src/couch/src/couch_proc_manager.erl52
7 files changed, 91 insertions, 25 deletions
diff --git a/dev/run b/dev/run
index 5ab895eb1..5bf5fc0f5 100755
--- a/dev/run
+++ b/dev/run
@@ -273,16 +273,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(
@@ -413,15 +403,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
index 5e5f2cfe6..9438872c6 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
index a9e6e9bea..aae179aa7 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 215d7eabe..f384de3aa 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 2c55d0900..bf4ae448b 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 cd019dbb5..2427d67ab 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 04101f240..b6639288f 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 ->