Annotate

core/modulemanager.lua @ 5901:1d13f73af58e

certmanager: Default to using the server's cipher preference order by default, as clients have been shown to commonly select weak and insecure ciphers even when they support stronger ones
author Matthew Wild <mwild1@gmail.com>
date Sat, 09 Nov 2013 17:50:19 +0000
parent 5411:82b3ddba0ec7
child 5776:bd0ff8ae98a8
child 6034:ee14da71d3fc
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1523
841d61be198f Remove version number from copyright headers
Matthew Wild <mwild1@gmail.com>
parents: 1505
diff changeset
1 -- Prosody IM
2923
b7049746bd29 Update copyright headers for 2010
Matthew Wild <mwild1@gmail.com>
parents: 2828
diff changeset
2 -- Copyright (C) 2008-2010 Matthew Wild
b7049746bd29 Update copyright headers for 2010
Matthew Wild <mwild1@gmail.com>
parents: 2828
diff changeset
3 -- Copyright (C) 2008-2010 Waqas Hussain
519
cccd610a0ef9 Insert copyright/license headers
Matthew Wild <mwild1@gmail.com>
parents: 467
diff changeset
4 --
758
b1885732e979 GPL->MIT!
Matthew Wild <mwild1@gmail.com>
parents: 748
diff changeset
5 -- This project is MIT/X11 licensed. Please see the
b1885732e979 GPL->MIT!
Matthew Wild <mwild1@gmail.com>
parents: 748
diff changeset
6 -- COPYING file in the source package for more information.
519
cccd610a0ef9 Insert copyright/license headers
Matthew Wild <mwild1@gmail.com>
parents: 467
diff changeset
7 --
cccd610a0ef9 Insert copyright/license headers
Matthew Wild <mwild1@gmail.com>
parents: 467
diff changeset
8
438
193f9dd64f17 Bumper commit for the new modulemanager API \o/ Updates all the modules, though some more changes may be in store.
Matthew Wild <mwild1@gmail.com>
parents: 400
diff changeset
9 local logger = require "util.logger";
540
ec03f6968fa8 Added function add_feature to modules API (for adding disco features)
Waqas Hussain <waqas20@gmail.com>
parents: 519
diff changeset
10 local log = logger.init("modulemanager");
573
f6555ebf84ec Move module loading to modulemanager
Matthew Wild <mwild1@gmail.com>
parents: 569
diff changeset
11 local config = require "core.configmanager";
1360
857034905016 modulemanager: Changed to use util.pluginloader
Waqas Hussain <waqas20@gmail.com>
parents: 1346
diff changeset
12 local pluginloader = require "util.pluginloader";
4896
27cda15104f2 modulemanager, moduleapi: Turn module.event_handlers into a multitable and track object->event->handler associations correctly (thanks Zash)
Matthew Wild <mwild1@gmail.com>
parents: 4893
diff changeset
13 local set = require "util.set";
27cda15104f2 modulemanager, moduleapi: Turn module.event_handlers into a multitable and track object->event->handler associations correctly (thanks Zash)
Matthew Wild <mwild1@gmail.com>
parents: 4893
diff changeset
14
27cda15104f2 modulemanager, moduleapi: Turn module.event_handlers into a multitable and track object->event->handler associations correctly (thanks Zash)
Matthew Wild <mwild1@gmail.com>
parents: 4893
diff changeset
15 local new_multitable = require "util.multitable".new;
30
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
16
747
40837f3422ab modulemanager: Add get_host_type() API method, and fix up call_module_method to work properly
Matthew Wild <mwild1@gmail.com>
parents: 746
diff changeset
17 local hosts = hosts;
1247
4721e4124692 modulemanager: module:hook now allows global modules to hook events on the prosody.events object
Waqas Hussain <waqas20@gmail.com>
parents: 1231
diff changeset
18 local prosody = prosody;
747
40837f3422ab modulemanager: Add get_host_type() API method, and fix up call_module_method to work properly
Matthew Wild <mwild1@gmail.com>
parents: 746
diff changeset
19
4746
37020f4b6799 modulemanager: Remove unused function imports
Matthew Wild <mwild1@gmail.com>
parents: 4745
diff changeset
20 local pcall, xpcall = pcall, xpcall;
5021
85b2689dbcfe Eliminate direct setfenv usage
Florian Zeitz <florob@babelmonkeys.de>
parents: 4896
diff changeset
21 local setmetatable, rawget = setmetatable, rawget;
5411
82b3ddba0ec7 modulemanager: add missing ipairs import.
Marco Cirillo <maranda@lightwitch.org>
parents: 5410
diff changeset
22 local ipairs, pairs, type, tostring, t_insert = ipairs, pairs, type, tostring, table.insert;
2151
3bb7c1daa93f modulemanager: New module API methods for getting config options with type conversion, get_option_string, get_option_number, get_option_boolean, get_option_array, get_option_set
Matthew Wild <mwild1@gmail.com>
parents: 2072
diff changeset
23
2977
686f9a5a7f5e modulemanager: Log proper tracebacks on errors during module load/unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2951
diff changeset
24 local debug_traceback = debug.traceback;
686f9a5a7f5e modulemanager: Log proper tracebacks on errors during module load/unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2951
diff changeset
25 local unpack, select = unpack, select;
686f9a5a7f5e modulemanager: Log proper tracebacks on errors during module load/unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2951
diff changeset
26 pcall = function(f, ...)
686f9a5a7f5e modulemanager: Log proper tracebacks on errors during module load/unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2951
diff changeset
27 local n = select("#", ...);
686f9a5a7f5e modulemanager: Log proper tracebacks on errors during module load/unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2951
diff changeset
28 local params = {...};
3588
1e570ed17147 modulemanager: Fixed: Locally defined pcall wasn't returning return values of the called function.
Waqas Hussain <waqas20@gmail.com>
parents: 3587
diff changeset
29 return xpcall(function() return f(unpack(params, 1, n)) end, function(e) return tostring(e).."\n"..debug_traceback(); end);
2977
686f9a5a7f5e modulemanager: Log proper tracebacks on errors during module load/unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2951
diff changeset
30 end
686f9a5a7f5e modulemanager: Log proper tracebacks on errors during module load/unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2951
diff changeset
31
4565
5a2212d3468e modulemanager: include mod_c2s and mod_s2s into autoloaded modules.
Florian Zeitz <florob@babelmonkeys.de>
parents: 4537
diff changeset
32 local autoload_modules = {"presence", "message", "iq", "offline", "c2s", "s2s"};
4883
b798d59919b1 modulemanager: Components should inherit mod_s2s from global modules_enabled too
Matthew Wild <mwild1@gmail.com>
parents: 4853
diff changeset
33 local component_inheritable_modules = {"tls", "dialback", "iq", "s2s"};
1505
e19cb945c25b modulemanager: Small code improvement, move autoloaded modules list to the top of the file
Matthew Wild <mwild1@gmail.com>
parents: 1504
diff changeset
34
467
66f145f5c932 Update Makefile to now pass config paths to prosody. Update prosody, modulemanager and connectionlisteners to obey these paths.
Matthew Wild <mwild1@gmail.com>
parents: 439
diff changeset
35 -- We need this to let modules access the real global namespace
30
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
36 local _G = _G;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
37
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
38 module "modulemanager"
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
39
4531
c778ce7e3c78 modulemanager: Move in-module API functions to core.moduleapi (half the file size, yay)
Matthew Wild <mwild1@gmail.com>
parents: 4454
diff changeset
40 local api = _G.require "core.moduleapi"; -- Module API container
438
193f9dd64f17 Bumper commit for the new modulemanager API \o/ Updates all the modules, though some more changes may be in store.
Matthew Wild <mwild1@gmail.com>
parents: 400
diff changeset
41
4535
d46e9ad4fe8a modulemanager: Cleanup some unused variables, imports, whitespace and add a comment.
Matthew Wild <mwild1@gmail.com>
parents: 4534
diff changeset
42 -- [host] = { [module] = module_env }
584
eb0cea29c8d7 Temporary hack for global modules
Matthew Wild <mwild1@gmail.com>
parents: 579
diff changeset
43 local modulemap = { ["*"] = {} };
438
193f9dd64f17 Bumper commit for the new modulemanager API \o/ Updates all the modules, though some more changes may be in store.
Matthew Wild <mwild1@gmail.com>
parents: 400
diff changeset
44
573
f6555ebf84ec Move module loading to modulemanager
Matthew Wild <mwild1@gmail.com>
parents: 569
diff changeset
45 -- Load modules when a host is activated
f6555ebf84ec Move module loading to modulemanager
Matthew Wild <mwild1@gmail.com>
parents: 569
diff changeset
46 function load_modules_for_host(host)
5377
898454038524 core.*: Complete removal of all traces of the "core" section and section-related code.
Kim Alvefur <zash@zash.se>
parents: 5192
diff changeset
47 local component = config.get(host, "component_module");
3595
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
48
5377
898454038524 core.*: Complete removal of all traces of the "core" section and section-related code.
Kim Alvefur <zash@zash.se>
parents: 5192
diff changeset
49 local global_modules_enabled = config.get("*", "modules_enabled");
898454038524 core.*: Complete removal of all traces of the "core" section and section-related code.
Kim Alvefur <zash@zash.se>
parents: 5192
diff changeset
50 local global_modules_disabled = config.get("*", "modules_disabled");
898454038524 core.*: Complete removal of all traces of the "core" section and section-related code.
Kim Alvefur <zash@zash.se>
parents: 5192
diff changeset
51 local host_modules_enabled = config.get(host, "modules_enabled");
898454038524 core.*: Complete removal of all traces of the "core" section and section-related code.
Kim Alvefur <zash@zash.se>
parents: 5192
diff changeset
52 local host_modules_disabled = config.get(host, "modules_disabled");
3595
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
53
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
54 if host_modules_enabled == global_modules_enabled then host_modules_enabled = nil; end
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
55 if host_modules_disabled == global_modules_disabled then host_modules_disabled = nil; end
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
56
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
57 local global_modules = set.new(autoload_modules) + set.new(global_modules_enabled) - set.new(global_modules_disabled);
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
58 if component then
3596
bbeba9f2acf8 modulemanager: load_modules_for_host(): For components, the inherited modules are the intersection of the inheritable and global modules lists, not the difference.
Waqas Hussain <waqas20@gmail.com>
parents: 3595
diff changeset
59 global_modules = set.intersection(set.new(component_inheritable_modules), global_modules);
1960
1e674dae31ae modulemanager: Re-organise module loading to still work when no global modules_enabled is defined in the config (thanks hoelzro for accidentally discovering this one)
Matthew Wild <mwild1@gmail.com>
parents: 1946
diff changeset
60 end
4135
9dfb3c0101b5 modulemanager: Fix disabling a module on a single host
Paul Aurich <paul@darkrain42.org>
parents: 4002
diff changeset
61 local modules = (global_modules + set.new(host_modules_enabled)) - set.new(host_modules_disabled);
3595
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
62
3758
41f174b61b6a modulemanager, mod_console: Rename mod_console -> mod_admin_telnet - add compatibility code to modulemanager for existing configs
Matthew Wild <mwild1@gmail.com>
parents: 3677
diff changeset
63 -- COMPAT w/ pre 0.8
41f174b61b6a modulemanager, mod_console: Rename mod_console -> mod_admin_telnet - add compatibility code to modulemanager for existing configs
Matthew Wild <mwild1@gmail.com>
parents: 3677
diff changeset
64 if modules:contains("console") then
41f174b61b6a modulemanager, mod_console: Rename mod_console -> mod_admin_telnet - add compatibility code to modulemanager for existing configs
Matthew Wild <mwild1@gmail.com>
parents: 3677
diff changeset
65 log("error", "The mod_console plugin has been renamed to mod_admin_telnet. Please update your config.");
41f174b61b6a modulemanager, mod_console: Rename mod_console -> mod_admin_telnet - add compatibility code to modulemanager for existing configs
Matthew Wild <mwild1@gmail.com>
parents: 3677
diff changeset
66 modules:remove("console");
41f174b61b6a modulemanager, mod_console: Rename mod_console -> mod_admin_telnet - add compatibility code to modulemanager for existing configs
Matthew Wild <mwild1@gmail.com>
parents: 3677
diff changeset
67 modules:add("admin_telnet");
41f174b61b6a modulemanager, mod_console: Rename mod_console -> mod_admin_telnet - add compatibility code to modulemanager for existing configs
Matthew Wild <mwild1@gmail.com>
parents: 3677
diff changeset
68 end
41f174b61b6a modulemanager, mod_console: Rename mod_console -> mod_admin_telnet - add compatibility code to modulemanager for existing configs
Matthew Wild <mwild1@gmail.com>
parents: 3677
diff changeset
69
3595
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
70 if component then
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
71 load(host, component);
637
30b8ad9f7b70 Fix for not loading global modules when host-specific modules are specified in config
Matthew Wild <mwild1@gmail.com>
parents: 615
diff changeset
72 end
3595
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
73 for module in modules do
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
74 load(host, module);
573
f6555ebf84ec Move module loading to modulemanager
Matthew Wild <mwild1@gmail.com>
parents: 569
diff changeset
75 end
f6555ebf84ec Move module loading to modulemanager
Matthew Wild <mwild1@gmail.com>
parents: 569
diff changeset
76 end
4533
c6480d17be1e modulemanager: Drop unnecessary prosody_events local
Matthew Wild <mwild1@gmail.com>
parents: 4532
diff changeset
77 prosody.events.add_handler("host-activated", load_modules_for_host);
4733
791388f90156 modulemanager: Clear modulemap when a host is deactivated (thanks xnyhps)
Matthew Wild <mwild1@gmail.com>
parents: 4728
diff changeset
78 prosody.events.add_handler("host-deactivated", function (host)
791388f90156 modulemanager: Clear modulemap when a host is deactivated (thanks xnyhps)
Matthew Wild <mwild1@gmail.com>
parents: 4728
diff changeset
79 modulemap[host] = nil;
791388f90156 modulemanager: Clear modulemap when a host is deactivated (thanks xnyhps)
Matthew Wild <mwild1@gmail.com>
parents: 4728
diff changeset
80 end);
30
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
81
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
82 --- Private helpers ---
438
193f9dd64f17 Bumper commit for the new modulemanager API \o/ Updates all the modules, though some more changes may be in store.
Matthew Wild <mwild1@gmail.com>
parents: 400
diff changeset
83
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
84 local function do_unload_module(host, name)
2278
8c10f13c0c20 modulemanager, net.dns: Remove trailing whitespace
Matthew Wild <mwild1@gmail.com>
parents: 2270
diff changeset
85 local mod = get_module(host, name);
439
6608ad3a72f3 is_loaded() and incomplete unload() for modules
Matthew Wild <mwild1@gmail.com>
parents: 438
diff changeset
86 if not mod then return nil, "module-not-loaded"; end
6608ad3a72f3 is_loaded() and incomplete unload() for modules
Matthew Wild <mwild1@gmail.com>
parents: 438
diff changeset
87
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
88 if module_has_method(mod, "unload") then
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
89 local ok, err = call_module_method(mod, "unload");
439
6608ad3a72f3 is_loaded() and incomplete unload() for modules
Matthew Wild <mwild1@gmail.com>
parents: 438
diff changeset
90 if (not ok) and err then
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
91 log("warn", "Non-fatal error unloading module '%s' on '%s': %s", name, host, err);
439
6608ad3a72f3 is_loaded() and incomplete unload() for modules
Matthew Wild <mwild1@gmail.com>
parents: 438
diff changeset
92 end
674
4f506c627b49 modulemanager: module.unload now gets called when modules are being unloaded
Waqas Hussain <waqas20@gmail.com>
parents: 670
diff changeset
93 end
4534
7a0a31c4f6c5 modulemanager, moduleapi: Replace hooks multitable with an event_handlers map stored in individual modules. Also adds module:hook_object_event() to hook events on any util.events compatible object.
Matthew Wild <mwild1@gmail.com>
parents: 4533
diff changeset
94
4896
27cda15104f2 modulemanager, moduleapi: Turn module.event_handlers into a multitable and track object->event->handler associations correctly (thanks Zash)
Matthew Wild <mwild1@gmail.com>
parents: 4893
diff changeset
95 for object, event, handler in mod.module.event_handlers:iter(nil, nil, nil) do
27cda15104f2 modulemanager, moduleapi: Turn module.event_handlers into a multitable and track object->event->handler associations correctly (thanks Zash)
Matthew Wild <mwild1@gmail.com>
parents: 4893
diff changeset
96 object.remove_handler(event, handler);
1259
6bd11bca9725 modulemanager: Keep track of event handlers added by module:hook, and remove them on module unload
Waqas Hussain <waqas20@gmail.com>
parents: 1253
diff changeset
97 end
4534
7a0a31c4f6c5 modulemanager, moduleapi: Replace hooks multitable with an event_handlers map stored in individual modules. Also adds module:hook_object_event() to hook events on any util.events compatible object.
Matthew Wild <mwild1@gmail.com>
parents: 4533
diff changeset
98
2828
fbddc3ed0d09 modulemanager: Fire item-removed events on module unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2072
diff changeset
99 if mod.module.items then -- remove items
4604
eef5e3a83792 modulemanager: Use appropriate events object for global modules when firing item-removed on unload
Matthew Wild <mwild1@gmail.com>
parents: 4565
diff changeset
100 local events = (host == "*" and prosody.events) or hosts[host].events;
2828
fbddc3ed0d09 modulemanager: Fire item-removed events on module unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2072
diff changeset
101 for key,t in pairs(mod.module.items) do
fbddc3ed0d09 modulemanager: Fire item-removed events on module unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2072
diff changeset
102 for i = #t,1,-1 do
fbddc3ed0d09 modulemanager: Fire item-removed events on module unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2072
diff changeset
103 local value = t[i];
fbddc3ed0d09 modulemanager: Fire item-removed events on module unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2072
diff changeset
104 t[i] = nil;
4604
eef5e3a83792 modulemanager: Use appropriate events object for global modules when firing item-removed on unload
Matthew Wild <mwild1@gmail.com>
parents: 4565
diff changeset
105 events.fire_event("item-removed/"..key, {source = mod.module, item = value});
2828
fbddc3ed0d09 modulemanager: Fire item-removed events on module unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2072
diff changeset
106 end
fbddc3ed0d09 modulemanager: Fire item-removed events on module unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2072
diff changeset
107 end
fbddc3ed0d09 modulemanager: Fire item-removed events on module unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2072
diff changeset
108 end
4665
6be91ca54613 modulemanager: Set module.loaded = false on unload
Matthew Wild <mwild1@gmail.com>
parents: 4662
diff changeset
109 mod.module.loaded = false;
1986
d4ba9d94eb74 modulemanager: Slightly rearranged code for more robust unloading of modules.
Waqas Hussain <waqas20@gmail.com>
parents: 1960
diff changeset
110 modulemap[host][name] = nil;
670
d5cf10b7fc44 Modulemanager: Basic modules can now be unloaded correctly
Waqas Hussain <waqas20@gmail.com>
parents: 637
diff changeset
111 return true;
439
6608ad3a72f3 is_loaded() and incomplete unload() for modules
Matthew Wild <mwild1@gmail.com>
parents: 438
diff changeset
112 end
6608ad3a72f3 is_loaded() and incomplete unload() for modules
Matthew Wild <mwild1@gmail.com>
parents: 438
diff changeset
113
5192
3fc3a3072cc2 modulemanager: Set module.reloading when a module is reloading, and when loading make the saved state available in module.saved_state (if any)
Matthew Wild <mwild1@gmail.com>
parents: 5123
diff changeset
114 local function do_load_module(host, module_name, state)
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
115 if not (host and module_name) then
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
116 return nil, "insufficient-parameters";
4638
352cd61e2682 modulemanager: Allow loading a module onto "*" (part-fixes #228)
Matthew Wild <mwild1@gmail.com>
parents: 4606
diff changeset
117 elseif not hosts[host] and host ~= "*"then
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
118 return nil, "unknown-host";
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
119 end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
120
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
121 if not modulemap[host] then
5123
7c5c86fa552e hostmanager, modulemanager: Ensure hosts[*].modules always exists.
Waqas Hussain <waqas20@gmail.com>
parents: 5021
diff changeset
122 modulemap[host] = hosts[host].modules;
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
123 end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
124
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
125 if modulemap[host][module_name] then
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
126 log("warn", "%s is already loaded for %s, so not loading again", module_name, host);
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
127 return nil, "module-already-loaded";
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
128 elseif modulemap["*"][module_name] then
4642
c1602c07d14d modulemanager: Support for shared modules - function module.add_host(host_module) in a global module
Matthew Wild <mwild1@gmail.com>
parents: 4641
diff changeset
129 local mod = modulemap["*"][module_name];
c1602c07d14d modulemanager: Support for shared modules - function module.add_host(host_module) in a global module
Matthew Wild <mwild1@gmail.com>
parents: 4641
diff changeset
130 if module_has_method(mod, "add_host") then
c1602c07d14d modulemanager: Support for shared modules - function module.add_host(host_module) in a global module
Matthew Wild <mwild1@gmail.com>
parents: 4641
diff changeset
131 local _log = logger.init(host..":"..module_name);
c1602c07d14d modulemanager: Support for shared modules - function module.add_host(host_module) in a global module
Matthew Wild <mwild1@gmail.com>
parents: 4641
diff changeset
132 local host_module_api = setmetatable({
4896
27cda15104f2 modulemanager, moduleapi: Turn module.event_handlers into a multitable and track object->event->handler associations correctly (thanks Zash)
Matthew Wild <mwild1@gmail.com>
parents: 4893
diff changeset
133 host = host, event_handlers = new_multitable(), items = {};
4642
c1602c07d14d modulemanager: Support for shared modules - function module.add_host(host_module) in a global module
Matthew Wild <mwild1@gmail.com>
parents: 4641
diff changeset
134 _log = _log, log = function (self, ...) return _log(...); end;
c1602c07d14d modulemanager: Support for shared modules - function module.add_host(host_module) in a global module
Matthew Wild <mwild1@gmail.com>
parents: 4641
diff changeset
135 },{
c1602c07d14d modulemanager: Support for shared modules - function module.add_host(host_module) in a global module
Matthew Wild <mwild1@gmail.com>
parents: 4641
diff changeset
136 __index = modulemap["*"][module_name].module;
c1602c07d14d modulemanager: Support for shared modules - function module.add_host(host_module) in a global module
Matthew Wild <mwild1@gmail.com>
parents: 4641
diff changeset
137 });
4728
7c81b04a4fed modulemanager: Set module.environment before calling add_host, otherwise the module will get the parent's environment (thanks xnyhps and Maranda)
Matthew Wild <mwild1@gmail.com>
parents: 4665
diff changeset
138 local host_module = setmetatable({ module = host_module_api }, { __index = mod });
7c81b04a4fed modulemanager: Set module.environment before calling add_host, otherwise the module will get the parent's environment (thanks xnyhps and Maranda)
Matthew Wild <mwild1@gmail.com>
parents: 4665
diff changeset
139 host_module_api.environment = host_module;
4776
dbe9d75c0452 modulemanager: Fixes to handle circular dependencies in module:depends()
Matthew Wild <mwild1@gmail.com>
parents: 4746
diff changeset
140 modulemap[host][module_name] = host_module;
4642
c1602c07d14d modulemanager: Support for shared modules - function module.add_host(host_module) in a global module
Matthew Wild <mwild1@gmail.com>
parents: 4641
diff changeset
141 local ok, result, module_err = call_module_method(mod, "add_host", host_module_api);
4776
dbe9d75c0452 modulemanager: Fixes to handle circular dependencies in module:depends()
Matthew Wild <mwild1@gmail.com>
parents: 4746
diff changeset
142 if not ok or result == false then
dbe9d75c0452 modulemanager: Fixes to handle circular dependencies in module:depends()
Matthew Wild <mwild1@gmail.com>
parents: 4746
diff changeset
143 modulemap[host][module_name] = nil;
dbe9d75c0452 modulemanager: Fixes to handle circular dependencies in module:depends()
Matthew Wild <mwild1@gmail.com>
parents: 4746
diff changeset
144 return nil, ok and module_err or result;
dbe9d75c0452 modulemanager: Fixes to handle circular dependencies in module:depends()
Matthew Wild <mwild1@gmail.com>
parents: 4746
diff changeset
145 end
4642
c1602c07d14d modulemanager: Support for shared modules - function module.add_host(host_module) in a global module
Matthew Wild <mwild1@gmail.com>
parents: 4641
diff changeset
146 return host_module;
c1602c07d14d modulemanager: Support for shared modules - function module.add_host(host_module) in a global module
Matthew Wild <mwild1@gmail.com>
parents: 4641
diff changeset
147 end
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
148 return nil, "global-module-already-loaded";
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
149 end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
150
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
151
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
152
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
153 local _log = logger.init(host..":"..module_name);
5021
85b2689dbcfe Eliminate direct setfenv usage
Florian Zeitz <florob@babelmonkeys.de>
parents: 4896
diff changeset
154 local api_instance = setmetatable({ name = module_name, host = host,
5192
3fc3a3072cc2 modulemanager: Set module.reloading when a module is reloading, and when loading make the saved state available in module.saved_state (if any)
Matthew Wild <mwild1@gmail.com>
parents: 5123
diff changeset
155 _log = _log, log = function (self, ...) return _log(...); end, event_handlers = new_multitable(),
3fc3a3072cc2 modulemanager: Set module.reloading when a module is reloading, and when loading make the saved state available in module.saved_state (if any)
Matthew Wild <mwild1@gmail.com>
parents: 5123
diff changeset
156 reloading = not not state, saved_state = state~=true and state or nil }
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
157 , { __index = api });
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
158
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
159 local pluginenv = setmetatable({ module = api_instance }, { __index = _G });
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
160 api_instance.environment = pluginenv;
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
161
5021
85b2689dbcfe Eliminate direct setfenv usage
Florian Zeitz <florob@babelmonkeys.de>
parents: 4896
diff changeset
162 local mod, err = pluginloader.load_code(module_name, nil, pluginenv);
85b2689dbcfe Eliminate direct setfenv usage
Florian Zeitz <florob@babelmonkeys.de>
parents: 4896
diff changeset
163 if not mod then
85b2689dbcfe Eliminate direct setfenv usage
Florian Zeitz <florob@babelmonkeys.de>
parents: 4896
diff changeset
164 log("error", "Unable to load module '%s': %s", module_name or "nil", err or "nil");
85b2689dbcfe Eliminate direct setfenv usage
Florian Zeitz <florob@babelmonkeys.de>
parents: 4896
diff changeset
165 return nil, err;
85b2689dbcfe Eliminate direct setfenv usage
Florian Zeitz <florob@babelmonkeys.de>
parents: 4896
diff changeset
166 end
85b2689dbcfe Eliminate direct setfenv usage
Florian Zeitz <florob@babelmonkeys.de>
parents: 4896
diff changeset
167
85b2689dbcfe Eliminate direct setfenv usage
Florian Zeitz <florob@babelmonkeys.de>
parents: 4896
diff changeset
168 api_instance.path = err;
85b2689dbcfe Eliminate direct setfenv usage
Florian Zeitz <florob@babelmonkeys.de>
parents: 4896
diff changeset
169
4776
dbe9d75c0452 modulemanager: Fixes to handle circular dependencies in module:depends()
Matthew Wild <mwild1@gmail.com>
parents: 4746
diff changeset
170 modulemap[host][module_name] = pluginenv;
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
171 local ok, err = pcall(mod);
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
172 if ok then
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
173 -- Call module's "load"
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
174 if module_has_method(pluginenv, "load") then
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
175 ok, err = call_module_method(pluginenv, "load");
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
176 if not ok then
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
177 log("warn", "Error loading module '%s' on '%s': %s", module_name, host, err or "nil");
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
178 end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
179 end
5192
3fc3a3072cc2 modulemanager: Set module.reloading when a module is reloading, and when loading make the saved state available in module.saved_state (if any)
Matthew Wild <mwild1@gmail.com>
parents: 5123
diff changeset
180 api_instance.reloading, api_instance.saved_state = nil, nil;
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
181
4639
98a29138dec8 modulemanager: Use api_instance rather than pluginenv.module (same thing)
Matthew Wild <mwild1@gmail.com>
parents: 4638
diff changeset
182 if api_instance.host == "*" then
98a29138dec8 modulemanager: Use api_instance rather than pluginenv.module (same thing)
Matthew Wild <mwild1@gmail.com>
parents: 4638
diff changeset
183 if not api_instance.global then -- COMPAT w/pre-0.9
4801
83cedf648b46 modulemanager: Hide deprecation warning for modules loaded on '*' directly (e.g. prosodyctl mod_<command>) (thanks Zash)
Matthew Wild <mwild1@gmail.com>
parents: 4776
diff changeset
184 if host ~= "*" then
83cedf648b46 modulemanager: Hide deprecation warning for modules loaded on '*' directly (e.g. prosodyctl mod_<command>) (thanks Zash)
Matthew Wild <mwild1@gmail.com>
parents: 4776
diff changeset
185 log("warn", "mod_%s: Setting module.host = '*' deprecated, call module:set_global() instead", module_name);
83cedf648b46 modulemanager: Hide deprecation warning for modules loaded on '*' directly (e.g. prosodyctl mod_<command>) (thanks Zash)
Matthew Wild <mwild1@gmail.com>
parents: 4776
diff changeset
186 end
4606
17785dbd9d58 modulemanager: Some refactoring. Deprecate module.host = "*", modules should call module:set_global() (which has been around since forever)
Matthew Wild <mwild1@gmail.com>
parents: 4604
diff changeset
187 api_instance:set_global();
17785dbd9d58 modulemanager: Some refactoring. Deprecate module.host = "*", modules should call module:set_global() (which has been around since forever)
Matthew Wild <mwild1@gmail.com>
parents: 4604
diff changeset
188 end
4776
dbe9d75c0452 modulemanager: Fixes to handle circular dependencies in module:depends()
Matthew Wild <mwild1@gmail.com>
parents: 4746
diff changeset
189 modulemap[host][module_name] = nil;
dbe9d75c0452 modulemanager: Fixes to handle circular dependencies in module:depends()
Matthew Wild <mwild1@gmail.com>
parents: 4746
diff changeset
190 modulemap[api_instance.host][module_name] = pluginenv;
4643
9008fc396fb1 modulemanager: When a shared module becomes global, ensure it still gets loaded onto the original target host
Matthew Wild <mwild1@gmail.com>
parents: 4642
diff changeset
191 if host ~= api_instance.host and module_has_method(pluginenv, "add_host") then
9008fc396fb1 modulemanager: When a shared module becomes global, ensure it still gets loaded onto the original target host
Matthew Wild <mwild1@gmail.com>
parents: 4642
diff changeset
192 -- Now load the module again onto the host it was originally being loaded on
4662
105423f77d46 modulemanager: Report errors that happen when loading a shared module onto its original host
Matthew Wild <mwild1@gmail.com>
parents: 4652
diff changeset
193 ok, err = do_load_module(host, module_name);
4643
9008fc396fb1 modulemanager: When a shared module becomes global, ensure it still gets loaded onto the original target host
Matthew Wild <mwild1@gmail.com>
parents: 4642
diff changeset
194 end
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
195 end
4606
17785dbd9d58 modulemanager: Some refactoring. Deprecate module.host = "*", modules should call module:set_global() (which has been around since forever)
Matthew Wild <mwild1@gmail.com>
parents: 4604
diff changeset
196 end
17785dbd9d58 modulemanager: Some refactoring. Deprecate module.host = "*", modules should call module:set_global() (which has been around since forever)
Matthew Wild <mwild1@gmail.com>
parents: 4604
diff changeset
197 if not ok then
4776
dbe9d75c0452 modulemanager: Fixes to handle circular dependencies in module:depends()
Matthew Wild <mwild1@gmail.com>
parents: 4746
diff changeset
198 modulemap[api_instance.host][module_name] = nil;
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
199 log("error", "Error initializing module '%s' on '%s': %s", module_name, host, err or "nil");
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
200 end
4537
d8d257c13562 modulemanager: load(): Return and use the correct module object
Matthew Wild <mwild1@gmail.com>
parents: 4535
diff changeset
201 return ok and pluginenv, err;
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
202 end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
203
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
204 local function do_reload_module(host, name)
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
205 local mod = get_module(host, name);
710
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
206 if not mod then return nil, "module-not-loaded"; end
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
207
1360
857034905016 modulemanager: Changed to use util.pluginloader
Waqas Hussain <waqas20@gmail.com>
parents: 1346
diff changeset
208 local _mod, err = pluginloader.load_code(name); -- checking for syntax errors
713
2afd6d9e21cd modulemanager: Check for syntax errors before reloading a module
Waqas Hussain <waqas20@gmail.com>
parents: 710
diff changeset
209 if not _mod then
1386
9132f16666e4 modulemanager: Fix copy/paste error, should be name instead of module_name
Matthew Wild <mwild1@gmail.com>
parents: 1378
diff changeset
210 log("error", "Unable to load module '%s': %s", name or "nil", err or "nil");
713
2afd6d9e21cd modulemanager: Check for syntax errors before reloading a module
Waqas Hussain <waqas20@gmail.com>
parents: 710
diff changeset
211 return nil, err;
2afd6d9e21cd modulemanager: Check for syntax errors before reloading a module
Waqas Hussain <waqas20@gmail.com>
parents: 710
diff changeset
212 end
2afd6d9e21cd modulemanager: Check for syntax errors before reloading a module
Waqas Hussain <waqas20@gmail.com>
parents: 710
diff changeset
213
710
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
214 local saved;
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
215 if module_has_method(mod, "save") then
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
216 local ok, ret, err = call_module_method(mod, "save");
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
217 if ok then
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
218 saved = ret;
710
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
219 else
4383
718445c040c4 modulemanager: Fix undefined global access in handling of module.save error handling.
Waqas Hussain <waqas20@gmail.com>
parents: 4381
diff changeset
220 log("warn", "Error saving module '%s:%s' state: %s", host, name, ret);
5377
898454038524 core.*: Complete removal of all traces of the "core" section and section-related code.
Kim Alvefur <zash@zash.se>
parents: 5192
diff changeset
221 if not config.get(host, "force_module_reload") then
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
222 log("warn", "Aborting reload due to error, set force_module_reload to ignore this");
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
223 return nil, "save-state-failed";
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
224 else
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
225 log("warn", "Continuing with reload (using the force)");
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
226 end
710
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
227 end
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
228 end
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
229
5192
3fc3a3072cc2 modulemanager: Set module.reloading when a module is reloading, and when loading make the saved state available in module.saved_state (if any)
Matthew Wild <mwild1@gmail.com>
parents: 5123
diff changeset
230 mod.module.reloading = true;
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
231 do_unload_module(host, name);
5192
3fc3a3072cc2 modulemanager: Set module.reloading when a module is reloading, and when loading make the saved state available in module.saved_state (if any)
Matthew Wild <mwild1@gmail.com>
parents: 5123
diff changeset
232 local ok, err = do_load_module(host, name, saved or true);
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
233 if ok then
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
234 mod = get_module(host, name);
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
235 if module_has_method(mod, "restore") then
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
236 local ok, err = call_module_method(mod, "restore", saved or {})
710
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
237 if (not ok) and err then
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
238 log("warn", "Error restoring module '%s' from '%s': %s", name, host, err);
710
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
239 end
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
240 end
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
241 end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
242 return ok and mod, err;
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
243 end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
244
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
245 --- Public API ---
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
246
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
247 -- Load a module and fire module-loaded event
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
248 function load(host, name)
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
249 local mod, err = do_load_module(host, name);
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
250 if mod then
4804
607414b26c8c modulemanager: Pass the module's final host (e.g. '*') to the module-loaded event
Matthew Wild <mwild1@gmail.com>
parents: 4801
diff changeset
251 (hosts[mod.module.host] or prosody).events.fire_event("module-loaded", { module = name, host = mod.module.host });
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
252 end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
253 return mod, err;
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
254 end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
255
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
256 -- Unload a module and fire module-unloaded
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
257 function unload(host, name)
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
258 local ok, err = do_unload_module(host, name);
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
259 if ok then
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
260 (hosts[host] or prosody).events.fire_event("module-unloaded", { module = name, host = host });
710
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
261 end
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
262 return ok, err;
710
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
263 end
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
264
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
265 function reload(host, name)
4853
4ca9328e37d5 modulemanager: Set module.reloading = true when firing module-reloaded event
Matthew Wild <mwild1@gmail.com>
parents: 4804
diff changeset
266 local mod, err = do_reload_module(host, name);
4ca9328e37d5 modulemanager: Set module.reloading = true when firing module-reloaded event
Matthew Wild <mwild1@gmail.com>
parents: 4804
diff changeset
267 if mod then
4ca9328e37d5 modulemanager: Set module.reloading = true when firing module-reloaded event
Matthew Wild <mwild1@gmail.com>
parents: 4804
diff changeset
268 modulemap[host][name].module.reloading = true;
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
269 (hosts[host] or prosody).events.fire_event("module-reloaded", { module = name, host = host });
4853
4ca9328e37d5 modulemanager: Set module.reloading = true when firing module-reloaded event
Matthew Wild <mwild1@gmail.com>
parents: 4804
diff changeset
270 mod.module.reloading = nil;
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
271 elseif not is_loaded(host, name) then
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
272 (hosts[host] or prosody).events.fire_event("module-unloaded", { module = name, host = host });
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
273 end
4853
4ca9328e37d5 modulemanager: Set module.reloading = true when firing module-reloaded event
Matthew Wild <mwild1@gmail.com>
parents: 4804
diff changeset
274 return mod, err;
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
275 end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
276
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
277 function get_module(host, name)
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
278 return modulemap[host] and modulemap[host][name];
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
279 end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
280
5410
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
281 function get_items(key, host)
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
282 local result = {};
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
283 local modules = modulemap[host];
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
284 if not key or not host or not modules then return nil; end
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
285
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
286 for _, module in pairs(modules) do
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
287 local mod = module.module;
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
288 if mod.items and mod.items[key] then
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
289 for _, value in ipairs(mod.items[key]) do
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
290 t_insert(result, value);
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
291 end
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
292 end
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
293 end
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
294
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
295 return result;
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
296 end
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
297
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
298 function get_modules(host)
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
299 return modulemap[host];
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
300 end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
301
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
302 function is_loaded(host, name)
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
303 return modulemap[host] and modulemap[host][name] and true;
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
304 end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
305
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
306 function module_has_method(module, method)
4641
2b3ee52fba32 modulemanager: Make module_has_method and module_call_method use rawget()
Matthew Wild <mwild1@gmail.com>
parents: 4640
diff changeset
307 return type(rawget(module.module, method)) == "function";
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
308 end
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
309
747
40837f3422ab modulemanager: Add get_host_type() API method, and fix up call_module_method to work properly
Matthew Wild <mwild1@gmail.com>
parents: 746
diff changeset
310 function call_module_method(module, method, ...)
4641
2b3ee52fba32 modulemanager: Make module_has_method and module_call_method use rawget()
Matthew Wild <mwild1@gmail.com>
parents: 4640
diff changeset
311 local f = rawget(module.module, method);
2b3ee52fba32 modulemanager: Make module_has_method and module_call_method use rawget()
Matthew Wild <mwild1@gmail.com>
parents: 4640
diff changeset
312 if type(f) == "function" then
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
313 return pcall(f, ...);
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
314 else
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
315 return false, "no-such-method";
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
316 end
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
317 end
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
318
39
89877d61ac51 Add support for arbitrary events and event hooks
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
319 return _M;