aboutsummaryrefslogtreecommitdiffstats
path: root/util/startup.lua
diff options
context:
space:
mode:
Diffstat (limited to 'util/startup.lua')
-rw-r--r--util/startup.lua157
1 files changed, 96 insertions, 61 deletions
diff --git a/util/startup.lua b/util/startup.lua
index 602dfe5e..5db1c51a 100644
--- a/util/startup.lua
+++ b/util/startup.lua
@@ -5,8 +5,10 @@ local startup = {};
local prosody = { events = require "util.events".new() };
local logger = require "util.logger";
local log = logger.init("startup");
+local parse_args = require "util.argparse".parse;
local config = require "core.configmanager";
+local config_warnings;
local dependencies = require "util.dependencies";
@@ -20,59 +22,38 @@ local default_gc_params = {
minor_threshold = 20, major_threshold = 50;
};
-local short_params = { D = "daemonize", F = "no-daemonize" };
-local value_params = { config = true };
-
-function startup.parse_args()
- local parsed_opts = {};
- prosody.opts = parsed_opts;
-
- if #arg == 0 then
- return;
- end
- while true do
- local raw_param = arg[1];
- if not raw_param then
- break;
- end
-
- local prefix = raw_param:match("^%-%-?");
- if not prefix then
- break;
- elseif prefix == "--" and raw_param == "--" then
- table.remove(arg, 1);
- break;
- end
- local param = table.remove(arg, 1):sub(#prefix+1);
- if #param == 1 then
- param = short_params[param];
- end
-
- if not param then
- print("Unknown command-line option: "..tostring(raw_param));
- print("Perhaps you meant to use prosodyctl instead?");
- os.exit(1);
- end
-
- local param_k, param_v;
- if value_params[param] then
- param_k, param_v = param, table.remove(arg, 1);
- if not param_v then
- print("Expected a value to follow command-line option: "..raw_param);
- os.exit(1);
- end
- else
- param_k, param_v = param:match("^([^=]+)=(.+)$");
- if not param_k then
- if param:match("^no%-") then
- param_k, param_v = param:sub(4), false;
- else
- param_k, param_v = param, true;
- end
+local arg_settigs = {
+ prosody = {
+ short_params = { D = "daemonize"; F = "no-daemonize", h = "help", ["?"] = "help" };
+ value_params = { config = true };
+ };
+ prosodyctl = {
+ short_params = { v = "verbose", h = "help", ["?"] = "help" };
+ value_params = { config = true };
+ };
+}
+
+function startup.parse_args(profile)
+ local opts, err, where = parse_args(arg, arg_settigs[profile or prosody.process_type] or profile);
+ if not opts then
+ if err == "param-not-found" then
+ print("Unknown command-line option: "..tostring(where));
+ if prosody.process_type == "prosody" then
+ print("Perhaps you meant to use prosodyctl instead?");
end
+ elseif err == "missing-value" then
+ print("Expected a value to follow command-line option: "..where);
end
- parsed_opts[param_k] = param_v;
+ os.exit(1);
+ end
+ if opts.help and prosody.process_type == "prosody" then
+ print("prosody [ -D | -F ] [ --config /path/to/prosody.cfg.lua ]");
+ print(" -D, --daemonize Run in the background")
+ print(" -F, --no-daemonize Run in the foreground")
+ print(" --config FILE Specify config file")
+ os.exit(0);
end
+ prosody.opts = opts;
end
function startup.read_config()
@@ -127,6 +108,8 @@ function startup.read_config()
print("**************************");
print("");
os.exit(1);
+ elseif err and #err > 0 then
+ config_warnings = err;
end
prosody.config_loaded = true;
end
@@ -159,8 +142,13 @@ function startup.init_logging()
end);
end
-function startup.log_dependency_warnings()
+function startup.log_startup_warnings()
dependencies.log_warnings();
+ if config_warnings then
+ for _, warning in ipairs(config_warnings) do
+ log("warn", "Configuration warning: %s", warning);
+ end
+ end
end
function startup.sanity_check()
@@ -229,8 +217,15 @@ function startup.set_function_metatable()
end
end
function mt.__tostring(f)
- local info = debug.getinfo(f);
- return ("function(%s:%d)"):format(info.short_src:match("[^\\/]*$"), info.linedefined);
+ local info = debug.getinfo(f, "Su");
+ local n_params = info.nparams or 0;
+ for i = 1, n_params do
+ info[i] = debug.getlocal(f, i);
+ end
+ if info.isvararg then
+ info[n_params+1] = "...";
+ end
+ return ("function<%s:%d>(%s)"):format(info.short_src:match("[^\\/]*$"), info.linedefined, table.concat(info, ", "));
end
debug.setmetatable(function() end, mt);
end
@@ -282,8 +277,8 @@ end
function startup.setup_plugindir()
local custom_plugin_paths = config.get("*", "plugin_paths");
+ local path_sep = package.config:sub(3,3);
if custom_plugin_paths then
- local path_sep = package.config:sub(3,3);
-- path1;path2;path3;defaultpath...
-- luacheck: ignore 111
CFG_PLUGINDIR = table.concat(custom_plugin_paths, path_sep)..path_sep..(CFG_PLUGINDIR or "plugins");
@@ -291,6 +286,17 @@ function startup.setup_plugindir()
end
end
+function startup.setup_plugin_install_path()
+ local installer_plugin_path = config.get("*", "installer_plugin_path") or "custom_plugins";
+ local path_sep = package.config:sub(3,3);
+ installer_plugin_path = config.resolve_relative_path(CFG_DATADIR or "data", installer_plugin_path);
+ require"util.paths".complement_lua_path(installer_plugin_path);
+ -- luacheck: ignore 111
+ CFG_PLUGINDIR = installer_plugin_path..path_sep..(CFG_PLUGINDIR or "plugins");
+ prosody.paths.installer = installer_plugin_path;
+ prosody.paths.plugins = CFG_PLUGINDIR;
+end
+
function startup.chdir()
if prosody.installed then
local lfs = require "lfs";
@@ -312,9 +318,9 @@ function startup.add_global_prosody_functions()
local ok, level, err = config.load(prosody.config_file);
if not ok then
if level == "parser" then
- log("error", "There was an error parsing the configuration file: %s", tostring(err));
+ log("error", "There was an error parsing the configuration file: %s", err);
elseif level == "file" then
- log("error", "Couldn't read the config file when trying to reload: %s", tostring(err));
+ log("error", "Couldn't read the config file when trying to reload: %s", err);
end
else
prosody.events.fire_event("config-reloaded", {
@@ -389,6 +395,21 @@ function startup.init_http_client()
{ capath = config_ssl.capath, cafile = config_ssl.cafile, verify = "peer", }, https_client);
end
+function startup.init_promise()
+ local promise = require "util.promise";
+
+ local timer = require "util.timer";
+ promise.set_nexttick(function(f) return timer.add_task(0, f); end);
+end
+
+function startup.init_async()
+ local async = require "util.async";
+
+ local timer = require "util.timer";
+ async.set_nexttick(function(f) return timer.add_task(0, f); end);
+ async.set_schedule_function(timer.add_task);
+end
+
function startup.init_data_store()
require "core.storagemanager";
end
@@ -448,7 +469,9 @@ end
-- Override logging config (used by prosodyctl)
function startup.force_console_logging()
original_logging_config = config.get("*", "log");
- config.set("*", "log", { { levels = { min = os.getenv("PROSODYCTL_LOG_LEVEL") or "info" }, to = "console" } });
+ local log_level = os.getenv("PROSODYCTL_LOG_LEVEL");
+ if not log_level and prosody.opts.verbose then log_level = "debug"; end
+ config.set("*", "log", { { levels = { min = log_level or "info" }, to = "console" } });
end
function startup.switch_user()
@@ -486,9 +509,9 @@ function startup.switch_user()
if not prosody.switched_user then
-- Boo!
print("Warning: Couldn't switch to Prosody user/group '"..tostring(desired_user).."'/'"..tostring(desired_group).."': "..tostring(err));
- else
+ elseif prosody.config_file then
-- Make sure the Prosody user can read the config
- local conf, err, errno = io.open(prosody.config_file);
+ local conf, err, errno = io.open(prosody.config_file); --luacheck: ignore 211/errno
if conf then
conf:close();
else
@@ -565,6 +588,10 @@ function startup.init_gc()
return true;
end
+function startup.init_errors()
+ require "util.error".configure(config.get("*", "error_library") or {});
+end
+
function startup.make_host(hostname)
return {
type = "local",
@@ -589,19 +616,22 @@ end
-- prosodyctl only
function startup.prosodyctl()
+ prosody.process_type = "prosodyctl";
startup.parse_args();
startup.init_global_state();
startup.read_config();
startup.force_console_logging();
startup.init_logging();
startup.init_gc();
+ startup.init_errors();
startup.setup_plugindir();
+ startup.setup_plugin_install_path();
startup.setup_datadir();
startup.chdir();
startup.read_version();
startup.switch_user();
startup.check_dependencies();
- startup.log_dependency_warnings();
+ startup.log_startup_warnings();
startup.check_unwriteable();
startup.load_libraries();
startup.init_http_client();
@@ -611,24 +641,29 @@ end
function startup.prosody()
-- These actions are in a strict order, as many depend on
-- previous steps to have already been performed
+ prosody.process_type = "prosody";
startup.parse_args();
startup.init_global_state();
startup.read_config();
startup.init_logging();
startup.init_gc();
+ startup.init_errors();
startup.sanity_check();
startup.sandbox_require();
startup.set_function_metatable();
startup.check_dependencies();
startup.load_libraries();
startup.setup_plugindir();
+ startup.setup_plugin_install_path();
startup.setup_datadir();
startup.chdir();
startup.add_global_prosody_functions();
startup.read_version();
startup.log_greeting();
- startup.log_dependency_warnings();
+ startup.log_startup_warnings();
startup.load_secondary_libraries();
+ startup.init_promise();
+ startup.init_async();
startup.init_http_client();
startup.init_data_store();
startup.init_global_protection();