Software /
code /
prosody
Comparison
util/startup.lua @ 11200:bf8f2da84007
Merge 0.11->trunk
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Thu, 05 Nov 2020 22:31:25 +0100 |
parent | 11152:89162d27e1b1 |
child | 11304:c022b582d312 |
comparison
equal
deleted
inserted
replaced
11199:6c7c50a4de32 | 11200:bf8f2da84007 |
---|---|
3 local startup = {}; | 3 local startup = {}; |
4 | 4 |
5 local prosody = { events = require "util.events".new() }; | 5 local prosody = { events = require "util.events".new() }; |
6 local logger = require "util.logger"; | 6 local logger = require "util.logger"; |
7 local log = logger.init("startup"); | 7 local log = logger.init("startup"); |
8 local parse_args = require "util.argparse".parse; | |
8 | 9 |
9 local config = require "core.configmanager"; | 10 local config = require "core.configmanager"; |
11 local config_warnings; | |
10 | 12 |
11 local dependencies = require "util.dependencies"; | 13 local dependencies = require "util.dependencies"; |
12 | 14 |
13 local original_logging_config; | 15 local original_logging_config; |
14 | 16 |
16 | 18 |
17 local short_params = { D = "daemonize", F = "no-daemonize" }; | 19 local short_params = { D = "daemonize", F = "no-daemonize" }; |
18 local value_params = { config = true }; | 20 local value_params = { config = true }; |
19 | 21 |
20 function startup.parse_args() | 22 function startup.parse_args() |
21 local parsed_opts = {}; | 23 local opts, err, where = parse_args(arg, { |
22 prosody.opts = parsed_opts; | 24 short_params = short_params, |
23 | 25 value_params = value_params, |
24 if #arg == 0 then | 26 }); |
25 return; | 27 if not opts then |
26 end | 28 if err == "param-not-found" then |
27 while true do | 29 print("Unknown command-line option: "..tostring(where)); |
28 local raw_param = arg[1]; | |
29 if not raw_param then | |
30 break; | |
31 end | |
32 | |
33 local prefix = raw_param:match("^%-%-?"); | |
34 if not prefix then | |
35 break; | |
36 elseif prefix == "--" and raw_param == "--" then | |
37 table.remove(arg, 1); | |
38 break; | |
39 end | |
40 local param = table.remove(arg, 1):sub(#prefix+1); | |
41 if #param == 1 then | |
42 param = short_params[param]; | |
43 end | |
44 | |
45 if not param then | |
46 print("Unknown command-line option: "..tostring(param)); | |
47 print("Perhaps you meant to use prosodyctl instead?"); | 30 print("Perhaps you meant to use prosodyctl instead?"); |
48 os.exit(1); | 31 elseif err == "missing-value" then |
49 end | 32 print("Expected a value to follow command-line option: "..where); |
50 | 33 end |
51 local param_k, param_v; | 34 os.exit(1); |
52 if value_params[param] then | 35 end |
53 param_k, param_v = param, table.remove(arg, 1); | 36 prosody.opts = opts; |
54 if not param_v then | |
55 print("Expected a value to follow command-line option: "..raw_param); | |
56 os.exit(1); | |
57 end | |
58 else | |
59 param_k, param_v = param:match("^([^=]+)=(.+)$"); | |
60 if not param_k then | |
61 if param:match("^no%-") then | |
62 param_k, param_v = param:sub(4), false; | |
63 else | |
64 param_k, param_v = param, true; | |
65 end | |
66 end | |
67 end | |
68 parsed_opts[param_k] = param_v; | |
69 end | |
70 end | 37 end |
71 | 38 |
72 function startup.read_config() | 39 function startup.read_config() |
73 local filenames = {}; | 40 local filenames = {}; |
74 | 41 |
119 print("More help on configuring Prosody can be found at https://prosody.im/doc/configure"); | 86 print("More help on configuring Prosody can be found at https://prosody.im/doc/configure"); |
120 print("Good luck!"); | 87 print("Good luck!"); |
121 print("**************************"); | 88 print("**************************"); |
122 print(""); | 89 print(""); |
123 os.exit(1); | 90 os.exit(1); |
91 elseif err and #err > 0 then | |
92 config_warnings = err; | |
124 end | 93 end |
125 prosody.config_loaded = true; | 94 prosody.config_loaded = true; |
126 end | 95 end |
127 | 96 |
128 function startup.check_dependencies() | 97 function startup.check_dependencies() |
151 loggingmanager.reload_logging(); | 120 loggingmanager.reload_logging(); |
152 prosody.events.fire_event("logging-reloaded"); | 121 prosody.events.fire_event("logging-reloaded"); |
153 end); | 122 end); |
154 end | 123 end |
155 | 124 |
156 function startup.log_dependency_warnings() | 125 function startup.log_startup_warnings() |
157 dependencies.log_warnings(); | 126 dependencies.log_warnings(); |
127 if config_warnings then | |
128 for _, warning in ipairs(config_warnings) do | |
129 log("warn", "Configuration warning: %s", warning); | |
130 end | |
131 end | |
158 end | 132 end |
159 | 133 |
160 function startup.sanity_check() | 134 function startup.sanity_check() |
161 for host, host_config in pairs(config.getconfig()) do | 135 for host, host_config in pairs(config.getconfig()) do |
162 if host ~= "*" | 136 if host ~= "*" |
221 if name then | 195 if name then |
222 debug.setupvalue(f, i, value); | 196 debug.setupvalue(f, i, value); |
223 end | 197 end |
224 end | 198 end |
225 function mt.__tostring(f) | 199 function mt.__tostring(f) |
226 local info = debug.getinfo(f); | 200 local info = debug.getinfo(f, "Su"); |
227 return ("function(%s:%d)"):format(info.short_src:match("[^\\/]*$"), info.linedefined); | 201 local n_params = info.nparams or 0; |
202 for i = 1, n_params do | |
203 info[i] = debug.getlocal(f, i); | |
204 end | |
205 if info.isvararg then | |
206 info[n_params+1] = "..."; | |
207 end | |
208 return ("function<%s:%d>(%s)"):format(info.short_src:match("[^\\/]*$"), info.linedefined, table.concat(info, ", ")); | |
228 end | 209 end |
229 debug.setmetatable(function() end, mt); | 210 debug.setmetatable(function() end, mt); |
230 end | 211 end |
231 | 212 |
232 function startup.detect_platform() | 213 function startup.detect_platform() |
274 prosody.paths.data = config.get("*", "data_path") or CFG_DATADIR or "data"; | 255 prosody.paths.data = config.get("*", "data_path") or CFG_DATADIR or "data"; |
275 end | 256 end |
276 | 257 |
277 function startup.setup_plugindir() | 258 function startup.setup_plugindir() |
278 local custom_plugin_paths = config.get("*", "plugin_paths"); | 259 local custom_plugin_paths = config.get("*", "plugin_paths"); |
260 local path_sep = package.config:sub(3,3); | |
279 if custom_plugin_paths then | 261 if custom_plugin_paths then |
280 local path_sep = package.config:sub(3,3); | |
281 -- path1;path2;path3;defaultpath... | 262 -- path1;path2;path3;defaultpath... |
282 -- luacheck: ignore 111 | 263 -- luacheck: ignore 111 |
283 CFG_PLUGINDIR = table.concat(custom_plugin_paths, path_sep)..path_sep..(CFG_PLUGINDIR or "plugins"); | 264 CFG_PLUGINDIR = table.concat(custom_plugin_paths, path_sep)..path_sep..(CFG_PLUGINDIR or "plugins"); |
284 prosody.paths.plugins = CFG_PLUGINDIR; | 265 prosody.paths.plugins = CFG_PLUGINDIR; |
285 end | 266 end |
267 end | |
268 | |
269 function startup.setup_plugin_install_path() | |
270 local installer_plugin_path = config.get("*", "installer_plugin_path") or (CFG_DATADIR or "data").."/custom_plugins"; | |
271 local path_sep = package.config:sub(3,3); | |
272 -- TODO Figure out what this should be relative to, because CWD could be anywhere | |
273 installer_plugin_path = config.resolve_relative_path(require "lfs".currentdir(), installer_plugin_path); | |
274 -- TODO Can probably move directory creation to the install command | |
275 require "lfs".mkdir(installer_plugin_path); | |
276 require"util.paths".complement_lua_path(installer_plugin_path); | |
277 -- luacheck: ignore 111 | |
278 CFG_PLUGINDIR = installer_plugin_path..path_sep..(CFG_PLUGINDIR or "plugins"); | |
279 prosody.paths.installer = installer_plugin_path; | |
280 prosody.paths.plugins = CFG_PLUGINDIR; | |
286 end | 281 end |
287 | 282 |
288 function startup.chdir() | 283 function startup.chdir() |
289 if prosody.installed then | 284 if prosody.installed then |
290 local lfs = require "lfs"; | 285 local lfs = require "lfs"; |
304 log("info", "Reloading configuration file"); | 299 log("info", "Reloading configuration file"); |
305 prosody.events.fire_event("reloading-config"); | 300 prosody.events.fire_event("reloading-config"); |
306 local ok, level, err = config.load(prosody.config_file); | 301 local ok, level, err = config.load(prosody.config_file); |
307 if not ok then | 302 if not ok then |
308 if level == "parser" then | 303 if level == "parser" then |
309 log("error", "There was an error parsing the configuration file: %s", tostring(err)); | 304 log("error", "There was an error parsing the configuration file: %s", err); |
310 elseif level == "file" then | 305 elseif level == "file" then |
311 log("error", "Couldn't read the config file when trying to reload: %s", tostring(err)); | 306 log("error", "Couldn't read the config file when trying to reload: %s", err); |
312 end | 307 end |
313 else | 308 else |
314 prosody.events.fire_event("config-reloaded", { | 309 prosody.events.fire_event("config-reloaded", { |
315 filename = prosody.config_file, | 310 filename = prosody.config_file, |
316 config = config.getconfig(), | 311 config = config.getconfig(), |
480 if not prosody.switched_user then | 475 if not prosody.switched_user then |
481 -- Boo! | 476 -- Boo! |
482 print("Warning: Couldn't switch to Prosody user/group '"..tostring(desired_user).."'/'"..tostring(desired_group).."': "..tostring(err)); | 477 print("Warning: Couldn't switch to Prosody user/group '"..tostring(desired_user).."'/'"..tostring(desired_group).."': "..tostring(err)); |
483 else | 478 else |
484 -- Make sure the Prosody user can read the config | 479 -- Make sure the Prosody user can read the config |
485 local conf, err, errno = io.open(prosody.config_file); | 480 local conf, err, errno = io.open(prosody.config_file); --luacheck: ignore 211/errno |
486 if conf then | 481 if conf then |
487 conf:close(); | 482 conf:close(); |
488 else | 483 else |
489 print("The config file is not readable by the '"..desired_user.."' user."); | 484 print("The config file is not readable by the '"..desired_user.."' user."); |
490 print("Prosody will not be able to read it."); | 485 print("Prosody will not be able to read it."); |
557 return nil, err; | 552 return nil, err; |
558 end | 553 end |
559 return true; | 554 return true; |
560 end | 555 end |
561 | 556 |
557 function startup.init_errors() | |
558 require "util.error".configure(config.get("*", "error_library") or {}); | |
559 end | |
560 | |
562 function startup.make_host(hostname) | 561 function startup.make_host(hostname) |
563 return { | 562 return { |
564 type = "local", | 563 type = "local", |
565 events = prosody.events, | 564 events = prosody.events, |
566 modules = {}, | 565 modules = {}, |
581 end | 580 end |
582 end | 581 end |
583 | 582 |
584 -- prosodyctl only | 583 -- prosodyctl only |
585 function startup.prosodyctl() | 584 function startup.prosodyctl() |
585 prosody.process_type = "prosodyctl"; | |
586 startup.parse_args(); | 586 startup.parse_args(); |
587 startup.init_global_state(); | 587 startup.init_global_state(); |
588 startup.read_config(); | 588 startup.read_config(); |
589 startup.force_console_logging(); | 589 startup.force_console_logging(); |
590 startup.init_logging(); | 590 startup.init_logging(); |
591 startup.init_gc(); | 591 startup.init_gc(); |
592 startup.init_errors(); | |
592 startup.setup_plugindir(); | 593 startup.setup_plugindir(); |
594 startup.setup_plugin_install_path(); | |
593 startup.setup_datadir(); | 595 startup.setup_datadir(); |
594 startup.chdir(); | 596 startup.chdir(); |
595 startup.read_version(); | 597 startup.read_version(); |
596 startup.switch_user(); | 598 startup.switch_user(); |
597 startup.check_dependencies(); | 599 startup.check_dependencies(); |
598 startup.log_dependency_warnings(); | 600 startup.log_startup_warnings(); |
599 startup.check_unwriteable(); | 601 startup.check_unwriteable(); |
600 startup.load_libraries(); | 602 startup.load_libraries(); |
601 startup.init_http_client(); | 603 startup.init_http_client(); |
602 startup.make_dummy_hosts(); | 604 startup.make_dummy_hosts(); |
603 end | 605 end |
604 | 606 |
605 function startup.prosody() | 607 function startup.prosody() |
606 -- These actions are in a strict order, as many depend on | 608 -- These actions are in a strict order, as many depend on |
607 -- previous steps to have already been performed | 609 -- previous steps to have already been performed |
610 prosody.process_type = "prosody"; | |
608 startup.parse_args(); | 611 startup.parse_args(); |
609 startup.init_global_state(); | 612 startup.init_global_state(); |
610 startup.read_config(); | 613 startup.read_config(); |
611 startup.init_logging(); | 614 startup.init_logging(); |
612 startup.init_gc(); | 615 startup.init_gc(); |
616 startup.init_errors(); | |
613 startup.sanity_check(); | 617 startup.sanity_check(); |
614 startup.sandbox_require(); | 618 startup.sandbox_require(); |
615 startup.set_function_metatable(); | 619 startup.set_function_metatable(); |
616 startup.check_dependencies(); | 620 startup.check_dependencies(); |
617 startup.load_libraries(); | 621 startup.load_libraries(); |
618 startup.setup_plugindir(); | 622 startup.setup_plugindir(); |
623 startup.setup_plugin_install_path(); | |
619 startup.setup_datadir(); | 624 startup.setup_datadir(); |
620 startup.chdir(); | 625 startup.chdir(); |
621 startup.add_global_prosody_functions(); | 626 startup.add_global_prosody_functions(); |
622 startup.read_version(); | 627 startup.read_version(); |
623 startup.log_greeting(); | 628 startup.log_greeting(); |
624 startup.log_dependency_warnings(); | 629 startup.log_startup_warnings(); |
625 startup.load_secondary_libraries(); | 630 startup.load_secondary_libraries(); |
626 startup.init_http_client(); | 631 startup.init_http_client(); |
627 startup.init_data_store(); | 632 startup.init_data_store(); |
628 startup.init_global_protection(); | 633 startup.init_global_protection(); |
629 startup.prepare_to_start(); | 634 startup.prepare_to_start(); |