core/modulemanager.lua
author Matthew Wild <mwild1@gmail.com>
Wed, 27 Mar 2024 15:35:15 +0000
branch0.12
changeset 13469 54a936345aaa
parent 12454 7efd4bcaa95c
child 12976 ead41e25ebc0
permissions -rw-r--r--
prosodyctl check: Warn about invalid domain names in the config file This ensures that domain names of virtual hosts and components are valid in XMPP, and that they are encoded correctly.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5411
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
12258
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
     9
local array = require "util.array";
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
    10
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
    11
local log = logger.init("modulemanager");
573
f6555ebf84ec Move module loading to modulemanager
Matthew Wild <mwild1@gmail.com>
parents: 569
diff changeset
    12
local config = require "core.configmanager";
1360
857034905016 modulemanager: Changed to use util.pluginloader
Waqas Hussain <waqas20@gmail.com>
parents: 1346
diff changeset
    13
local pluginloader = require "util.pluginloader";
11149
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
    14
local envload = require "util.envload";
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
    15
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
    16
12258
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    17
local core_features = require "core.features".available;
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    18
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
    19
local new_multitable = require "util.multitable".new;
6782
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6664
diff changeset
    20
local api = require "core.moduleapi"; -- Module API container
30
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    21
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
    22
local prosody = prosody;
8720
9ddd0fbbe53a core: Use prosody.hosts instead of _G.hosts for consistency
Kim Alvefur <zash@zash.se>
parents: 8558
diff changeset
    23
local hosts = prosody.hosts;
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
    24
9565
acf74ad0b795 Many things: switch from hacky multi-arg xpcall implementations to a standard util.xpcall
Matthew Wild <mwild1@gmail.com>
parents: 8919
diff changeset
    25
local xpcall = require "util.xpcall".xpcall;
9566
732314eb3258 modulemanager: Fix issues introduced in previous commit acf74ad0b795 [thanks luacheck, scansion]
Matthew Wild <mwild1@gmail.com>
parents: 9565
diff changeset
    26
local debug_traceback = debug.traceback;
5021
85b2689dbcfe Eliminate direct setfenv usage
Florian Zeitz <florob@babelmonkeys.de>
parents: 4896
diff changeset
    27
local setmetatable, rawget = setmetatable, rawget;
9566
732314eb3258 modulemanager: Fix issues introduced in previous commit acf74ad0b795 [thanks luacheck, scansion]
Matthew Wild <mwild1@gmail.com>
parents: 9565
diff changeset
    28
local ipairs, pairs, type, t_insert = ipairs, pairs, type, table.insert;
11149
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
    29
local lua_version = _VERSION:match("5%.%d$");
2977
686f9a5a7f5e modulemanager: Log proper tracebacks on errors during module load/unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2951
diff changeset
    30
10292
f36f7d2c269b core.modulemanager: Split lists across multiple lines for improved readability
Kim Alvefur <zash@zash.se>
parents: 10254
diff changeset
    31
local autoload_modules = {
f36f7d2c269b core.modulemanager: Split lists across multiple lines for improved readability
Kim Alvefur <zash@zash.se>
parents: 10254
diff changeset
    32
	prosody.platform,
f36f7d2c269b core.modulemanager: Split lists across multiple lines for improved readability
Kim Alvefur <zash@zash.se>
parents: 10254
diff changeset
    33
	"presence",
f36f7d2c269b core.modulemanager: Split lists across multiple lines for improved readability
Kim Alvefur <zash@zash.se>
parents: 10254
diff changeset
    34
	"message",
f36f7d2c269b core.modulemanager: Split lists across multiple lines for improved readability
Kim Alvefur <zash@zash.se>
parents: 10254
diff changeset
    35
	"iq",
f36f7d2c269b core.modulemanager: Split lists across multiple lines for improved readability
Kim Alvefur <zash@zash.se>
parents: 10254
diff changeset
    36
	"offline",
f36f7d2c269b core.modulemanager: Split lists across multiple lines for improved readability
Kim Alvefur <zash@zash.se>
parents: 10254
diff changeset
    37
	"c2s",
f36f7d2c269b core.modulemanager: Split lists across multiple lines for improved readability
Kim Alvefur <zash@zash.se>
parents: 10254
diff changeset
    38
	"s2s",
f36f7d2c269b core.modulemanager: Split lists across multiple lines for improved readability
Kim Alvefur <zash@zash.se>
parents: 10254
diff changeset
    39
	"s2s_auth_certs",
f36f7d2c269b core.modulemanager: Split lists across multiple lines for improved readability
Kim Alvefur <zash@zash.se>
parents: 10254
diff changeset
    40
};
f36f7d2c269b core.modulemanager: Split lists across multiple lines for improved readability
Kim Alvefur <zash@zash.se>
parents: 10254
diff changeset
    41
local component_inheritable_modules = {
f36f7d2c269b core.modulemanager: Split lists across multiple lines for improved readability
Kim Alvefur <zash@zash.se>
parents: 10254
diff changeset
    42
	"tls",
f36f7d2c269b core.modulemanager: Split lists across multiple lines for improved readability
Kim Alvefur <zash@zash.se>
parents: 10254
diff changeset
    43
	"saslauth",
f36f7d2c269b core.modulemanager: Split lists across multiple lines for improved readability
Kim Alvefur <zash@zash.se>
parents: 10254
diff changeset
    44
	"dialback",
f36f7d2c269b core.modulemanager: Split lists across multiple lines for improved readability
Kim Alvefur <zash@zash.se>
parents: 10254
diff changeset
    45
	"iq",
f36f7d2c269b core.modulemanager: Split lists across multiple lines for improved readability
Kim Alvefur <zash@zash.se>
parents: 10254
diff changeset
    46
	"s2s",
f36f7d2c269b core.modulemanager: Split lists across multiple lines for improved readability
Kim Alvefur <zash@zash.se>
parents: 10254
diff changeset
    47
	"s2s_bidi",
12083
76a5c0261793 core.modulemanager: Load mod_smacks on Components
Kim Alvefur <zash@zash.se>
parents: 11589
diff changeset
    48
	"smacks",
11589
057ce005937e core.modulemanager: Inherit mod_server_contact_info onto components #1270
Kim Alvefur <zash@zash.se>
parents: 11291
diff changeset
    49
	"server_contact_info",
10292
f36f7d2c269b core.modulemanager: Split lists across multiple lines for improved readability
Kim Alvefur <zash@zash.se>
parents: 10254
diff changeset
    50
};
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
    51
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
    52
-- We need this to let modules access the real global namespace
30
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    53
local _G = _G;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    54
6782
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6664
diff changeset
    55
local _ENV = nil;
8558
4f0f5b49bb03 vairious: Add annotation when an empty environment is set [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7950
diff changeset
    56
-- luacheck: std none
30
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    57
12257
57d35fcde488 modulemanager, moduleapi: Switch to new pluginloader interface
Matthew Wild <mwild1@gmail.com>
parents: 12150
diff changeset
    58
local loader = pluginloader.init({
12258
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    59
	load_filter_cb = function (path, content)
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    60
		local metadata = {};
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    61
		for line in content:gmatch("([^\r\n]+)\r?\n") do
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    62
			local key, value = line:match("^%-%-%% *([%w_]+): *(.+)$");
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    63
			if key then
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    64
				value = value:gsub("%s+$", "");
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    65
				metadata[key] = value;
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    66
			end
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    67
		end
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    68
12261
7adfd5d29576 modulemanager: Shorten metadata keys to improve readability and memorability
Matthew Wild <mwild1@gmail.com>
parents: 12258
diff changeset
    69
		if metadata.conflicts then
7adfd5d29576 modulemanager: Shorten metadata keys to improve readability and memorability
Matthew Wild <mwild1@gmail.com>
parents: 12258
diff changeset
    70
			local conflicts_features = set.new(array.collect(metadata.conflicts:gmatch("[^, ]+")));
7adfd5d29576 modulemanager: Shorten metadata keys to improve readability and memorability
Matthew Wild <mwild1@gmail.com>
parents: 12258
diff changeset
    71
			local conflicted_features = set.intersection(conflicts_features, core_features);
12258
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    72
			if not conflicted_features:empty() then
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    73
				log("warn", "Not loading module, due to conflicting features '%s': %s", conflicted_features, path);
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    74
				return; -- Don't load this module
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    75
			end
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    76
		end
12261
7adfd5d29576 modulemanager: Shorten metadata keys to improve readability and memorability
Matthew Wild <mwild1@gmail.com>
parents: 12258
diff changeset
    77
		if metadata.requires then
7adfd5d29576 modulemanager: Shorten metadata keys to improve readability and memorability
Matthew Wild <mwild1@gmail.com>
parents: 12258
diff changeset
    78
			local required_features = set.new(array.collect(metadata.requires:gmatch("[^, ]+")));
12258
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    79
			local missing_features = required_features - core_features;
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    80
			if not missing_features:empty() then
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    81
				log("warn", "Not loading module, due to missing features '%s': %s", missing_features, path);
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    82
				return; -- Don't load this module
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    83
			end
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    84
		end
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    85
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    86
		return path, content, metadata;
5b0c8e499288 modulemanager: Add plugin load filter that reads module metadata from source
Matthew Wild <mwild1@gmail.com>
parents: 12257
diff changeset
    87
	end;
12257
57d35fcde488 modulemanager, moduleapi: Switch to new pluginloader interface
Matthew Wild <mwild1@gmail.com>
parents: 12150
diff changeset
    88
});
57d35fcde488 modulemanager, moduleapi: Switch to new pluginloader interface
Matthew Wild <mwild1@gmail.com>
parents: 12150
diff changeset
    89
7950
24170d74b00b core: Split some very long lines [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7306
diff changeset
    90
local load_modules_for_host, load, unload, reload, get_module, get_items;
24170d74b00b core: Split some very long lines [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7306
diff changeset
    91
local get_modules, is_loaded, module_has_method, call_module_method;
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
    92
4535
d46e9ad4fe8a modulemanager: Cleanup some unused variables, imports, whitespace and add a comment.
Matthew Wild <mwild1@gmail.com>
parents: 4534
diff changeset
    93
-- [host] = { [module] = module_env }
584
eb0cea29c8d7 Temporary hack for global modules
Matthew Wild <mwild1@gmail.com>
parents: 579
diff changeset
    94
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
    95
8919
e727747279a0 modulemanager: Expose function to get the list of modules that should be loaded on a host
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
    96
-- Get the list of modules to be loaded on a host
e727747279a0 modulemanager: Expose function to get the list of modules that should be loaded on a host
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
    97
local function get_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
    98
	local component = config.get(host, "component_module");
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5411
diff changeset
    99
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
   100
	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
   101
	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
   102
	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
   103
	local host_modules_disabled = config.get(host, "modules_disabled");
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5411
diff changeset
   104
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
   105
	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
   106
	if host_modules_disabled == global_modules_disabled then host_modules_disabled = nil; end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5411
diff changeset
   107
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
   108
	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
   109
	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
   110
		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
   111
	end
4135
9dfb3c0101b5 modulemanager: Fix disabling a module on a single host
Paul Aurich <paul@darkrain42.org>
parents: 4002
diff changeset
   112
	local modules = (global_modules + set.new(host_modules_enabled)) - set.new(host_modules_disabled);
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5411
diff changeset
   113
10437
7777f25d5266 core.modulemanager: Disable mod_vcard if mod_vcard_legacy is enabled to prevent conflict (#1469)
Kim Alvefur <zash@zash.se>
parents: 9566
diff changeset
   114
	if modules:contains("vcard") and modules:contains("vcard_legacy") then
7777f25d5266 core.modulemanager: Disable mod_vcard if mod_vcard_legacy is enabled to prevent conflict (#1469)
Kim Alvefur <zash@zash.se>
parents: 9566
diff changeset
   115
		log("error", "The mod_vcard_legacy plugin replaces mod_vcard but both are enabled. Please update your config.");
7777f25d5266 core.modulemanager: Disable mod_vcard if mod_vcard_legacy is enabled to prevent conflict (#1469)
Kim Alvefur <zash@zash.se>
parents: 9566
diff changeset
   116
		modules:remove("vcard");
7777f25d5266 core.modulemanager: Disable mod_vcard if mod_vcard_legacy is enabled to prevent conflict (#1469)
Kim Alvefur <zash@zash.se>
parents: 9566
diff changeset
   117
	end
7777f25d5266 core.modulemanager: Disable mod_vcard if mod_vcard_legacy is enabled to prevent conflict (#1469)
Kim Alvefur <zash@zash.se>
parents: 9566
diff changeset
   118
8919
e727747279a0 modulemanager: Expose function to get the list of modules that should be loaded on a host
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   119
	return modules, component;
e727747279a0 modulemanager: Expose function to get the list of modules that should be loaded on a host
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   120
end
e727747279a0 modulemanager: Expose function to get the list of modules that should be loaded on a host
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   121
e727747279a0 modulemanager: Expose function to get the list of modules that should be loaded on a host
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   122
-- Load modules when a host is activated
e727747279a0 modulemanager: Expose function to get the list of modules that should be loaded on a host
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   123
function load_modules_for_host(host)
e727747279a0 modulemanager: Expose function to get the list of modules that should be loaded on a host
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   124
	local modules, component_module = get_modules_for_host(host);
e727747279a0 modulemanager: Expose function to get the list of modules that should be loaded on a host
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   125
e727747279a0 modulemanager: Expose function to get the list of modules that should be loaded on a host
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   126
	-- Ensure component module is loaded first
e727747279a0 modulemanager: Expose function to get the list of modules that should be loaded on a host
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   127
	if component_module then
e727747279a0 modulemanager: Expose function to get the list of modules that should be loaded on a host
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   128
		load(host, component_module);
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
   129
	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
   130
	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
   131
		load(host, module);
573
f6555ebf84ec Move module loading to modulemanager
Matthew Wild <mwild1@gmail.com>
parents: 569
diff changeset
   132
	end
f6555ebf84ec Move module loading to modulemanager
Matthew Wild <mwild1@gmail.com>
parents: 569
diff changeset
   133
end
4533
c6480d17be1e modulemanager: Drop unnecessary prosody_events local
Matthew Wild <mwild1@gmail.com>
parents: 4532
diff changeset
   134
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
   135
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
   136
	modulemap[host] = nil;
791388f90156 modulemanager: Clear modulemap when a host is deactivated (thanks xnyhps)
Matthew Wild <mwild1@gmail.com>
parents: 4728
diff changeset
   137
end);
30
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   138
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
   139
--- 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
   140
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
   141
local function do_unload_module(host, name)
2278
8c10f13c0c20 modulemanager, net.dns: Remove trailing whitespace
Matthew Wild <mwild1@gmail.com>
parents: 2270
diff changeset
   142
	local mod = get_module(host, name);
439
6608ad3a72f3 is_loaded() and incomplete unload() for modules
Matthew Wild <mwild1@gmail.com>
parents: 438
diff changeset
   143
	if not mod then return nil, "module-not-loaded"; end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5411
diff changeset
   144
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   145
	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
   146
		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
   147
		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
   148
			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
   149
		end
674
4f506c627b49 modulemanager: module.unload now gets called when modules are being unloaded
Waqas Hussain <waqas20@gmail.com>
parents: 670
diff changeset
   150
	end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5411
diff changeset
   151
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
   152
	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
   153
		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
   154
	end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5411
diff changeset
   155
2828
fbddc3ed0d09 modulemanager: Fire item-removed events on module unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2072
diff changeset
   156
	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
   157
		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
   158
		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
   159
			for i = #t,1,-1 do
fbddc3ed0d09 modulemanager: Fire item-removed events on module unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2072
diff changeset
   160
				local value = t[i];
fbddc3ed0d09 modulemanager: Fire item-removed events on module unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2072
diff changeset
   161
				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
   162
				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
   163
			end
fbddc3ed0d09 modulemanager: Fire item-removed events on module unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2072
diff changeset
   164
		end
fbddc3ed0d09 modulemanager: Fire item-removed events on module unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2072
diff changeset
   165
	end
4665
6be91ca54613 modulemanager: Set module.loaded = false on unload
Matthew Wild <mwild1@gmail.com>
parents: 4662
diff changeset
   166
	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
   167
	modulemap[host][name] = nil;
670
d5cf10b7fc44 Modulemanager: Basic modules can now be unloaded correctly
Waqas Hussain <waqas20@gmail.com>
parents: 637
diff changeset
   168
	return true;
439
6608ad3a72f3 is_loaded() and incomplete unload() for modules
Matthew Wild <mwild1@gmail.com>
parents: 438
diff changeset
   169
end
6608ad3a72f3 is_loaded() and incomplete unload() for modules
Matthew Wild <mwild1@gmail.com>
parents: 438
diff changeset
   170
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
   171
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
   172
	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
   173
		return nil, "insufficient-parameters";
4638
352cd61e2682 modulemanager: Allow loading a module onto "*" (part-fixes #228)
Matthew Wild <mwild1@gmail.com>
parents: 4606
diff changeset
   174
	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
   175
		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
   176
	end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5411
diff changeset
   177
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
   178
	if not modulemap[host] then
5123
7c5c86fa552e hostmanager, modulemanager: Ensure hosts[*].modules always exists.
Waqas Hussain <waqas20@gmail.com>
parents: 5021
diff changeset
   179
		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
   180
	end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5411
diff changeset
   181
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
   182
	if modulemap[host][module_name] then
7306
439d00063620 modulemanager: Silence log message about attempts to load already loaded modules for shared modules
Kim Alvefur <zash@zash.se>
parents: 7166
diff changeset
   183
		if not modulemap["*"][module_name] then
439d00063620 modulemanager: Silence log message about attempts to load already loaded modules for shared modules
Kim Alvefur <zash@zash.se>
parents: 7166
diff changeset
   184
			log("debug", "%s is already loaded for %s, so not loading again", module_name, host);
439d00063620 modulemanager: Silence log message about attempts to load already loaded modules for shared modules
Kim Alvefur <zash@zash.se>
parents: 7166
diff changeset
   185
		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
   186
		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
   187
	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
   188
		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
   189
		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
   190
			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
   191
			local host_module_api = setmetatable({
12454
7efd4bcaa95c core.modulemanager: Fix global flag on per-host instances of shared modules (fix #1736)
Kim Alvefur <zash@zash.se>
parents: 12279
diff changeset
   192
				global = false,
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
   193
				host = host, event_handlers = new_multitable(), items = {};
6664
90e846e8a788 modulemanager: Add luacheck annotations
Matthew Wild <mwild1@gmail.com>
parents: 6663
diff changeset
   194
				_log = _log, log = function (self, ...) return _log(...); end; --luacheck: ignore 212/self
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
   195
			},{
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
   196
				__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
   197
			});
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
   198
			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
   199
			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
   200
			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
   201
			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
   202
			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
   203
				modulemap[host][module_name] = nil;
dbe9d75c0452 modulemanager: Fixes to handle circular dependencies in module:depends()
Matthew Wild <mwild1@gmail.com>
parents: 4746
diff changeset
   204
				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
   205
			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
   206
			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
   207
		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
   208
		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
   209
	end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5411
diff changeset
   210
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
   211
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
   212
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
   213
	local _log = logger.init(host..":"..module_name);
5021
85b2689dbcfe Eliminate direct setfenv usage
Florian Zeitz <florob@babelmonkeys.de>
parents: 4896
diff changeset
   214
	local api_instance = setmetatable({ name = module_name, host = host,
6664
90e846e8a788 modulemanager: Add luacheck annotations
Matthew Wild <mwild1@gmail.com>
parents: 6663
diff changeset
   215
		_log = _log, log = function (self, ...) return _log(...); end, --luacheck: ignore 212/self
90e846e8a788 modulemanager: Add luacheck annotations
Matthew Wild <mwild1@gmail.com>
parents: 6663
diff changeset
   216
		event_handlers = new_multitable(), reloading = not not state,
90e846e8a788 modulemanager: Add luacheck annotations
Matthew Wild <mwild1@gmail.com>
parents: 6663
diff changeset
   217
		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
   218
		, { __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
   219
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
   220
	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
   221
	api_instance.environment = pluginenv;
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5411
diff changeset
   222
12279
13624194984b core.modulemanager: Save module metadata for potential later use
Kim Alvefur <zash@zash.se>
parents: 12261
diff changeset
   223
	local mod, err, meta = loader:load_code(module_name, nil, pluginenv);
5021
85b2689dbcfe Eliminate direct setfenv usage
Florian Zeitz <florob@babelmonkeys.de>
parents: 4896
diff changeset
   224
	if not mod then
85b2689dbcfe Eliminate direct setfenv usage
Florian Zeitz <florob@babelmonkeys.de>
parents: 4896
diff changeset
   225
		log("error", "Unable to load module '%s': %s", module_name or "nil", err or "nil");
9871
984f27e4b8a3 modulemanager: Set module status on successful or failed module load
Matthew Wild <mwild1@gmail.com>
parents: 9566
diff changeset
   226
		api_instance:set_status("error", "Failed to load (see log)");
5021
85b2689dbcfe Eliminate direct setfenv usage
Florian Zeitz <florob@babelmonkeys.de>
parents: 4896
diff changeset
   227
		return nil, err;
85b2689dbcfe Eliminate direct setfenv usage
Florian Zeitz <florob@babelmonkeys.de>
parents: 4896
diff changeset
   228
	end
85b2689dbcfe Eliminate direct setfenv usage
Florian Zeitz <florob@babelmonkeys.de>
parents: 4896
diff changeset
   229
85b2689dbcfe Eliminate direct setfenv usage
Florian Zeitz <florob@babelmonkeys.de>
parents: 4896
diff changeset
   230
	api_instance.path = err;
12279
13624194984b core.modulemanager: Save module metadata for potential later use
Kim Alvefur <zash@zash.se>
parents: 12261
diff changeset
   231
	api_instance.meta = meta;
5021
85b2689dbcfe Eliminate direct setfenv usage
Florian Zeitz <florob@babelmonkeys.de>
parents: 4896
diff changeset
   232
11149
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   233
	local custom_plugins = prosody.paths.installer;
11155
498b3ab49b9c core.modulemanager: Fix error if installer path missing
Kim Alvefur <zash@zash.se>
parents: 11151
diff changeset
   234
	if custom_plugins and err:sub(1, #custom_plugins+1) == custom_plugins.."/" then
11149
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   235
		-- Stage 1: Make it work (you are here)
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   236
		-- Stage 2: Make it less hacky (TODO)
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   237
		local manifest = {};
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   238
		local luarocks_path = custom_plugins.."/lib/luarocks/rocks-"..lua_version;
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   239
		local manifest_filename = luarocks_path.."/manifest";
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   240
		local load_manifest, err = envload.envloadfile(manifest_filename, manifest);
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   241
		if not load_manifest then
11151
82d6c8e627b9 core.modulemanager: Add compat for LuaRocks 2.x
Kim Alvefur <zash@zash.se>
parents: 11149
diff changeset
   242
			-- COMPAT Luarocks 2.x
82d6c8e627b9 core.modulemanager: Add compat for LuaRocks 2.x
Kim Alvefur <zash@zash.se>
parents: 11149
diff changeset
   243
			log("debug", "Could not load LuaRocks 3.x manifest, trying 2.x", err);
11291
b602dd3c4bbc core.modulemanager: Fix resource location compat with LuaRocks 2.x
Kim Alvefur <zash@zash.se>
parents: 11155
diff changeset
   244
			luarocks_path = custom_plugins.."/lib/luarocks/rocks";
11151
82d6c8e627b9 core.modulemanager: Add compat for LuaRocks 2.x
Kim Alvefur <zash@zash.se>
parents: 11149
diff changeset
   245
			manifest_filename = luarocks_path.."/manifest";
82d6c8e627b9 core.modulemanager: Add compat for LuaRocks 2.x
Kim Alvefur <zash@zash.se>
parents: 11149
diff changeset
   246
			load_manifest, err = envload.envloadfile(manifest_filename, manifest);
82d6c8e627b9 core.modulemanager: Add compat for LuaRocks 2.x
Kim Alvefur <zash@zash.se>
parents: 11149
diff changeset
   247
		end
82d6c8e627b9 core.modulemanager: Add compat for LuaRocks 2.x
Kim Alvefur <zash@zash.se>
parents: 11149
diff changeset
   248
		if not load_manifest then
11149
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   249
			log("error", "Could not load manifest of installed plugins: %s", err, load_manifest);
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   250
		else
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   251
			local ok, err = xpcall(load_manifest, debug_traceback);
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   252
			if not ok then
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   253
				log("error", "Could not load manifest of installed plugins: %s", err);
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   254
			elseif type(manifest.modules) ~= "table" then
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   255
				log("debug", "Expected 'table' but manifest.modules = %q", manifest.modules);
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   256
				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);
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   257
			else
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   258
				local versions = manifest.modules["mod_"..module_name];
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   259
				if type(versions) == "table" and versions[1] then
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   260
					-- Not going to deal with multiple installed versions
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   261
					api_instance.resource_path = luarocks_path.."/"..versions[1];
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   262
				else
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   263
					log("debug", "mod_%s does not appear in the installation manifest", module_name);
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   264
				end
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   265
			end
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   266
		end
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   267
	end
be73df6765b9 core.modulemanager: Locate resources of LuaRocks-installed modules
Kim Alvefur <zash@zash.se>
parents: 10534
diff changeset
   268
4776
dbe9d75c0452 modulemanager: Fixes to handle circular dependencies in module:depends()
Matthew Wild <mwild1@gmail.com>
parents: 4746
diff changeset
   269
	modulemap[host][module_name] = pluginenv;
9566
732314eb3258 modulemanager: Fix issues introduced in previous commit acf74ad0b795 [thanks luacheck, scansion]
Matthew Wild <mwild1@gmail.com>
parents: 9565
diff changeset
   270
	local ok, err = xpcall(mod, debug_traceback);
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
	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
   272
		-- 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
   273
		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
   274
			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
   275
			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
   276
				log("warn", "Error loading module '%s' on '%s': %s", module_name, host, err or "nil");
9871
984f27e4b8a3 modulemanager: Set module status on successful or failed module load
Matthew Wild <mwild1@gmail.com>
parents: 9566
diff changeset
   277
				api_instance:set_status("warn", "Error during load (see log)");
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
   278
			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
   279
		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
   280
		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
   281
4639
98a29138dec8 modulemanager: Use api_instance rather than pluginenv.module (same thing)
Matthew Wild <mwild1@gmail.com>
parents: 4638
diff changeset
   282
		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
   283
			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
   284
				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
   285
					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
   286
				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
   287
				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
   288
			end
4776
dbe9d75c0452 modulemanager: Fixes to handle circular dependencies in module:depends()
Matthew Wild <mwild1@gmail.com>
parents: 4746
diff changeset
   289
			modulemap[host][module_name] = nil;
dbe9d75c0452 modulemanager: Fixes to handle circular dependencies in module:depends()
Matthew Wild <mwild1@gmail.com>
parents: 4746
diff changeset
   290
			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
   291
			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
   292
				-- 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
   293
				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
   294
			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
   295
		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
   296
	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
   297
	if not ok then
4776
dbe9d75c0452 modulemanager: Fixes to handle circular dependencies in module:depends()
Matthew Wild <mwild1@gmail.com>
parents: 4746
diff changeset
   298
		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
   299
		log("error", "Error initializing module '%s' on '%s': %s", module_name, host, err or "nil");
9871
984f27e4b8a3 modulemanager: Set module status on successful or failed module load
Matthew Wild <mwild1@gmail.com>
parents: 9566
diff changeset
   300
		api_instance:set_status("warn", "Error during load (see log)");
984f27e4b8a3 modulemanager: Set module status on successful or failed module load
Matthew Wild <mwild1@gmail.com>
parents: 9566
diff changeset
   301
	else
984f27e4b8a3 modulemanager: Set module status on successful or failed module load
Matthew Wild <mwild1@gmail.com>
parents: 9566
diff changeset
   302
		api_instance:set_status("core", "Loaded", false);
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
   303
	end
4537
d8d257c13562 modulemanager: load(): Return and use the correct module object
Matthew Wild <mwild1@gmail.com>
parents: 4535
diff changeset
   304
	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
   305
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
   306
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
   307
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
   308
	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
   309
	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
   310
12257
57d35fcde488 modulemanager, moduleapi: Switch to new pluginloader interface
Matthew Wild <mwild1@gmail.com>
parents: 12150
diff changeset
   311
	local _mod, err = loader: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
   312
	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
   313
		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
   314
		return nil, err;
2afd6d9e21cd modulemanager: Check for syntax errors before reloading a module
Waqas Hussain <waqas20@gmail.com>
parents: 710
diff changeset
   315
	end
2afd6d9e21cd modulemanager: Check for syntax errors before reloading a module
Waqas Hussain <waqas20@gmail.com>
parents: 710
diff changeset
   316
710
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
   317
	local saved;
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   318
	if module_has_method(mod, "save") then
10534
67d56dacc79c core.modulemanager: Silence warning about unused err variable [luacheck]
Kim Alvefur <zash@zash.se>
parents: 10438
diff changeset
   319
		-- FIXME What goes in 'err' here?
67d56dacc79c core.modulemanager: Silence warning about unused err variable [luacheck]
Kim Alvefur <zash@zash.se>
parents: 10438
diff changeset
   320
		local ok, ret, err = call_module_method(mod, "save"); -- luacheck: ignore 211/err
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   321
		if ok then
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   322
			saved = ret;
710
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
   323
		else
4383
718445c040c4 modulemanager: Fix undefined global access in handling of module.save error handling.
Waqas Hussain <waqas20@gmail.com>
parents: 4381
diff changeset
   324
			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
   325
			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
   326
				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
   327
				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
   328
			else
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   329
				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
   330
			end
710
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
   331
		end
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
   332
	end
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
   333
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
   334
	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
   335
	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
   336
	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
   337
	if ok then
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   338
		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
   339
		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
   340
			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
   341
			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
   342
				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
   343
			end
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
   344
		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
   345
	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
   346
	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
   347
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
   348
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
   349
--- 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
   350
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
   351
-- 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
   352
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
   353
	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
   354
	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
   355
		(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
   356
	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
   357
	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
   358
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
   359
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
   360
-- 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
   361
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
   362
	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
   363
	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
   364
		(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
   365
	end
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   366
	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
   367
end
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
   368
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
   369
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
   370
	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
   371
	if mod then
4ca9328e37d5 modulemanager: Set module.reloading = true when firing module-reloaded event
Matthew Wild <mwild1@gmail.com>
parents: 4804
diff changeset
   372
		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
   373
		(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
   374
		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
   375
	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
   376
		(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
   377
	end
4853
4ca9328e37d5 modulemanager: Set module.reloading = true when firing module-reloaded event
Matthew Wild <mwild1@gmail.com>
parents: 4804
diff changeset
   378
	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
   379
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
   380
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
   381
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
   382
	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
   383
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
   384
5410
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
   385
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
   386
	local result = {};
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
   387
	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
   388
	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
   389
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
   390
	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
   391
		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
   392
		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
   393
			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
   394
				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
   395
			end
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
   396
		end
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
   397
	end
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
   398
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
   399
	return result;
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
   400
end
bea93cfd6c54 modulemanager: add function to retrieve module items from a specific host entity.
Marco Cirillo <maranda@lightwitch.org>
parents: 5377
diff changeset
   401
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
   402
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
   403
	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
   404
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
   405
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
   406
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
   407
	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
   408
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
   409
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   410
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
   411
	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
   412
end
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   413
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
   414
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
   415
	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
   416
	if type(f) == "function" then
9566
732314eb3258 modulemanager: Fix issues introduced in previous commit acf74ad0b795 [thanks luacheck, scansion]
Matthew Wild <mwild1@gmail.com>
parents: 9565
diff changeset
   417
		return xpcall(f, debug_traceback, ...);
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   418
	else
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   419
		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
   420
	end
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   421
end
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   422
6782
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6664
diff changeset
   423
return {
8919
e727747279a0 modulemanager: Expose function to get the list of modules that should be loaded on a host
Matthew Wild <mwild1@gmail.com>
parents: 8720
diff changeset
   424
	get_modules_for_host = get_modules_for_host;
6782
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6664
diff changeset
   425
	load_modules_for_host = load_modules_for_host;
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6664
diff changeset
   426
	load = load;
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6664
diff changeset
   427
	unload = unload;
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6664
diff changeset
   428
	reload = reload;
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6664
diff changeset
   429
	get_module = get_module;
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6664
diff changeset
   430
	get_items = get_items;
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6664
diff changeset
   431
	get_modules = get_modules;
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6664
diff changeset
   432
	is_loaded = is_loaded;
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6664
diff changeset
   433
	module_has_method = module_has_method;
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6664
diff changeset
   434
	call_module_method = call_module_method;
12257
57d35fcde488 modulemanager, moduleapi: Switch to new pluginloader interface
Matthew Wild <mwild1@gmail.com>
parents: 12150
diff changeset
   435
57d35fcde488 modulemanager, moduleapi: Switch to new pluginloader interface
Matthew Wild <mwild1@gmail.com>
parents: 12150
diff changeset
   436
	loader = loader;
6782
6236668da30a core.*: Remove use of module() function
Kim Alvefur <zash@zash.se>
parents: 6664
diff changeset
   437
};