comparison core/modulemanager.lua @ 11200:bf8f2da84007

Merge 0.11->trunk
author Kim Alvefur <zash@zash.se>
date Thu, 05 Nov 2020 22:31:25 +0100
parents 498b3ab49b9c
children b602dd3c4bbc
comparison
equal deleted inserted replaced
11199:6c7c50a4de32 11200:bf8f2da84007
8 8
9 local logger = require "util.logger"; 9 local logger = require "util.logger";
10 local log = logger.init("modulemanager"); 10 local log = logger.init("modulemanager");
11 local config = require "core.configmanager"; 11 local config = require "core.configmanager";
12 local pluginloader = require "util.pluginloader"; 12 local pluginloader = require "util.pluginloader";
13 local envload = require "util.envload";
13 local set = require "util.set"; 14 local set = require "util.set";
14 15
15 local new_multitable = require "util.multitable".new; 16 local new_multitable = require "util.multitable".new;
16 local api = require "core.moduleapi"; -- Module API container 17 local api = require "core.moduleapi"; -- Module API container
17 18
20 21
21 local xpcall = require "util.xpcall".xpcall; 22 local xpcall = require "util.xpcall".xpcall;
22 local debug_traceback = debug.traceback; 23 local debug_traceback = debug.traceback;
23 local setmetatable, rawget = setmetatable, rawget; 24 local setmetatable, rawget = setmetatable, rawget;
24 local ipairs, pairs, type, t_insert = ipairs, pairs, type, table.insert; 25 local ipairs, pairs, type, t_insert = ipairs, pairs, type, table.insert;
25 26 local lua_version = _VERSION:match("5%.%d$");
26 local autoload_modules = {prosody.platform, "presence", "message", "iq", "offline", "c2s", "s2s", "s2s_auth_certs"}; 27
27 local component_inheritable_modules = {"tls", "saslauth", "dialback", "iq", "s2s"}; 28 local autoload_modules = {
29 prosody.platform,
30 "presence",
31 "message",
32 "iq",
33 "offline",
34 "c2s",
35 "s2s",
36 "s2s_auth_certs",
37 };
38 local component_inheritable_modules = {
39 "tls",
40 "saslauth",
41 "dialback",
42 "iq",
43 "s2s",
44 "s2s_bidi",
45 };
28 46
29 -- We need this to let modules access the real global namespace 47 -- We need this to let modules access the real global namespace
30 local _G = _G; 48 local _G = _G;
31 49
32 local _ENV = nil; 50 local _ENV = nil;
172 api_instance.environment = pluginenv; 190 api_instance.environment = pluginenv;
173 191
174 local mod, err = pluginloader.load_code(module_name, nil, pluginenv); 192 local mod, err = pluginloader.load_code(module_name, nil, pluginenv);
175 if not mod then 193 if not mod then
176 log("error", "Unable to load module '%s': %s", module_name or "nil", err or "nil"); 194 log("error", "Unable to load module '%s': %s", module_name or "nil", err or "nil");
195 api_instance:set_status("error", "Failed to load (see log)");
177 return nil, err; 196 return nil, err;
178 end 197 end
179 198
180 api_instance.path = err; 199 api_instance.path = err;
200
201 local custom_plugins = prosody.paths.installer;
202 if custom_plugins and err:sub(1, #custom_plugins+1) == custom_plugins.."/" then
203 -- Stage 1: Make it work (you are here)
204 -- Stage 2: Make it less hacky (TODO)
205 local manifest = {};
206 local luarocks_path = custom_plugins.."/lib/luarocks/rocks-"..lua_version;
207 local manifest_filename = luarocks_path.."/manifest";
208 local load_manifest, err = envload.envloadfile(manifest_filename, manifest);
209 if not load_manifest then
210 -- COMPAT Luarocks 2.x
211 log("debug", "Could not load LuaRocks 3.x manifest, trying 2.x", err);
212 luarocks_path = custom_plugins.."/lib/luarocks/rocks-"..lua_version;
213 manifest_filename = luarocks_path.."/manifest";
214 load_manifest, err = envload.envloadfile(manifest_filename, manifest);
215 end
216 if not load_manifest then
217 log("error", "Could not load manifest of installed plugins: %s", err, load_manifest);
218 else
219 local ok, err = xpcall(load_manifest, debug_traceback);
220 if not ok then
221 log("error", "Could not load manifest of installed plugins: %s", err);
222 elseif type(manifest.modules) ~= "table" then
223 log("debug", "Expected 'table' but manifest.modules = %q", manifest.modules);
224 log("error", "Can't look up resource path for mod_%s because '%s' does not appear to be a LuaRocks manifest", module_name, manifest_filename);
225 else
226 local versions = manifest.modules["mod_"..module_name];
227 if type(versions) == "table" and versions[1] then
228 -- Not going to deal with multiple installed versions
229 api_instance.resource_path = luarocks_path.."/"..versions[1];
230 else
231 log("debug", "mod_%s does not appear in the installation manifest", module_name);
232 end
233 end
234 end
235 end
181 236
182 modulemap[host][module_name] = pluginenv; 237 modulemap[host][module_name] = pluginenv;
183 local ok, err = xpcall(mod, debug_traceback); 238 local ok, err = xpcall(mod, debug_traceback);
184 if ok then 239 if ok then
185 -- Call module's "load" 240 -- Call module's "load"
186 if module_has_method(pluginenv, "load") then 241 if module_has_method(pluginenv, "load") then
187 ok, err = call_module_method(pluginenv, "load"); 242 ok, err = call_module_method(pluginenv, "load");
188 if not ok then 243 if not ok then
189 log("warn", "Error loading module '%s' on '%s': %s", module_name, host, err or "nil"); 244 log("warn", "Error loading module '%s' on '%s': %s", module_name, host, err or "nil");
245 api_instance:set_status("warn", "Error during load (see log)");
190 end 246 end
191 end 247 end
192 api_instance.reloading, api_instance.saved_state = nil, nil; 248 api_instance.reloading, api_instance.saved_state = nil, nil;
193 249
194 if api_instance.host == "*" then 250 if api_instance.host == "*" then
207 end 263 end
208 end 264 end
209 if not ok then 265 if not ok then
210 modulemap[api_instance.host][module_name] = nil; 266 modulemap[api_instance.host][module_name] = nil;
211 log("error", "Error initializing module '%s' on '%s': %s", module_name, host, err or "nil"); 267 log("error", "Error initializing module '%s' on '%s': %s", module_name, host, err or "nil");
268 api_instance:set_status("warn", "Error during load (see log)");
269 else
270 api_instance:set_status("core", "Loaded", false);
212 end 271 end
213 return ok and pluginenv, err; 272 return ok and pluginenv, err;
214 end 273 end
215 274
216 local function do_reload_module(host, name) 275 local function do_reload_module(host, name)
223 return nil, err; 282 return nil, err;
224 end 283 end
225 284
226 local saved; 285 local saved;
227 if module_has_method(mod, "save") then 286 if module_has_method(mod, "save") then
228 local ok, ret, err = call_module_method(mod, "save"); 287 -- FIXME What goes in 'err' here?
288 local ok, ret, err = call_module_method(mod, "save"); -- luacheck: ignore 211/err
229 if ok then 289 if ok then
230 saved = ret; 290 saved = ret;
231 else 291 else
232 log("warn", "Error saving module '%s:%s' state: %s", host, name, ret); 292 log("warn", "Error saving module '%s:%s' state: %s", host, name, ret);
233 if not config.get(host, "force_module_reload") then 293 if not config.get(host, "force_module_reload") then