aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Wild <mwild1@gmail.com>2019-08-19 12:17:17 +0100
committerMatthew Wild <mwild1@gmail.com>2019-08-19 12:17:17 +0100
commit9f32d30e97c325810bba0ce17fef4491fac2f365 (patch)
tree0b8157172fb508a4b962032d663b6d9b2e31a600
parent469ce79a49fabbe0d42115fa7a2f1a27e3bae3f1 (diff)
parent6ae5f04781c82e8064ceb9acc91ab9cfdb295969 (diff)
downloadprosody-9f32d30e97c325810bba0ce17fef4491fac2f365.tar.gz
prosody-9f32d30e97c325810bba0ce17fef4491fac2f365.zip
Merge mod-installer (2019 GSoC by João Duarte)
-rw-r--r--prosody.cfg.lua.dist4
-rwxr-xr-xprosodyctl29
-rw-r--r--tools/make_repo.lua44
-rw-r--r--util/paths.lua16
-rw-r--r--util/pluginloader.lua3
-rw-r--r--util/prosodyctl.lua38
-rw-r--r--util/startup.lua8
7 files changed, 138 insertions, 4 deletions
diff --git a/prosody.cfg.lua.dist b/prosody.cfg.lua.dist
index f7f7b731..0d74cf66 100644
--- a/prosody.cfg.lua.dist
+++ b/prosody.cfg.lua.dist
@@ -32,6 +32,10 @@ admins = { }
-- will look for modules first. For community modules, see https://modules.prosody.im/
--plugin_paths = {}
+-- Single directory for custom prosody plugins and/or Lua libraries installation
+-- This path takes priority over plugin_paths, when prosody is searching for modules
+--installer_plugin_path = ""
+
-- This is the list of modules Prosody will load on startup.
-- It looks for mod_modulename.lua in the plugins folder, so make sure that exists too.
-- Documentation for bundled modules can be found at: https://prosody.im/doc/modules
diff --git a/prosodyctl b/prosodyctl
index 3809beff..7261b326 100755
--- a/prosodyctl
+++ b/prosodyctl
@@ -10,7 +10,6 @@
-- prosodyctl - command-line controller for Prosody XMPP server
-- Will be modified by configure script if run --
-
CFG_SOURCEDIR=CFG_SOURCEDIR or os.getenv("PROSODY_SRCDIR");
CFG_CONFIGDIR=CFG_CONFIGDIR or os.getenv("PROSODY_CFGDIR");
CFG_PLUGINDIR=CFG_PLUGINDIR or os.getenv("PROSODY_PLUGINDIR");
@@ -77,6 +76,7 @@ local show_usage = prosodyctl.show_usage;
local show_yesno = prosodyctl.show_yesno;
local show_prompt = prosodyctl.show_prompt;
local read_password = prosodyctl.read_password;
+local call_luarocks = prosodyctl.call_luarocks;
local jid_split = require "util.jid".prepped_split;
@@ -85,6 +85,30 @@ local prosodyctl_timeout = (configmanager.get("*", "prosodyctl_timeout") or 5) *
local commands = {};
local command = table.remove(arg, 1);
+function commands.install(arg)
+ if arg[1] == "--help" then
+ show_usage([[install]], [[Installs a prosody/luarocks plugin]]);
+ return 1;
+ end
+ call_luarocks(arg[1], "install")
+end
+
+function commands.remove(arg)
+ if arg[1] == "--help" then
+ show_usage([[remove]], [[Removes a module installed in the working directory's plugins folder]]);
+ return 1;
+ end
+ call_luarocks(arg[1], "remove")
+end
+
+function commands.list(arg)
+ if arg[1] == "--help" then
+ show_usage([[list]], [[Shows installed rocks]]);
+ return 1;
+ end
+ call_luarocks(arg[1], "list")
+end
+
function commands.adduser(arg)
if not arg[1] or arg[1] == "--help" then
show_usage([[adduser JID]], [[Create the specified user account in Prosody]]);
@@ -1358,7 +1382,8 @@ local command_runner = async.runner(function ()
print("Where COMMAND may be one of:\n");
local hidden_commands = require "util.set".new{ "register", "unregister", "addplugin" };
- local commands_order = { "adduser", "passwd", "deluser", "start", "stop", "restart", "reload", "about" };
+ local commands_order = { "install", "remove", "list", "adduser", "passwd", "deluser", "start", "stop", "restart", "reload",
+ "about" };
local done = {};
diff --git a/tools/make_repo.lua b/tools/make_repo.lua
new file mode 100644
index 00000000..5b5e6234
--- /dev/null
+++ b/tools/make_repo.lua
@@ -0,0 +1,44 @@
+print("Getting all the available modules")
+if os.execute '[ -e "./downloaded_modules" ]' then
+ os.execute("rm -rf downloaded_modules")
+end
+os.execute("hg clone https://hg.prosody.im/prosody-modules/ downloaded_modules")
+local i, popen = 0, io.popen
+local flag = "mod_"
+if os.execute '[ -e "./repository" ]' then
+ os.execute("mkdir repository")
+end
+local pfile = popen('ls -a "downloaded_modules"')
+for filename in pfile:lines() do
+ i = i + 1
+ if filename:sub(1, #flag) == flag then
+ local file = io.open("repository/"..filename.."-scm-1.rockspec", "w")
+ file:write('package = "'..filename..'"', '\n')
+ file:write('version = "scm-1"', '\n')
+ file:write('source = {', '\n')
+ file:write('\turl = "hg+https://hg.prosody.im/prosody-modules",', '\n')
+ file:write('\tdir = "prosody-modules"', '\n')
+ file:write('}', '\n')
+ file:write('description = {', '\n')
+ file:write('\thomepage = "https://prosody.im/",', '\n')
+ file:write('\tlicense = "MIT"', '\n')
+ file:write('}', '\n')
+ file:write('dependencies = {', '\n')
+ file:write('\t"lua >= 5.1"', '\n')
+ file:write('}', '\n')
+ file:write('build = {', '\n')
+ file:write('\ttype = "builtin",', '\n')
+ file:write('\tmodules = {', '\n')
+ file:write('\t\t["'..filename..'.'..filename..'"] = "'..filename..'/'..filename..'.lua"', '\n')
+ file:write('\t}', '\n')
+ file:write('}', '\n')
+ file:close()
+ end
+end
+pfile:close()
+os.execute("cd repository/ && luarocks-admin make_manifest ./ && chmod -R 644 ./*")
+print("")
+print("Done!. Modules' sources are locally available at ./downloaded_modules")
+print("Repository is available at ./repository")
+print("The repository contains all of prosody modules' respective rockspecs, as well as manifest files and an html Index")
+print("You can now either point your server to this folder, or copy its contents to another configured folder.")
diff --git a/util/paths.lua b/util/paths.lua
index 89f4cad9..c225108a 100644
--- a/util/paths.lua
+++ b/util/paths.lua
@@ -41,4 +41,20 @@ function path_util.join(...)
return t_concat({...}, path_sep);
end
+function path_util.complement_lua_path(installer_plugin_path)
+ -- Checking for duplicates
+ -- The commands using luarocks need the path to the directory that has the /share and /lib folders.
+ local lua_version = _VERSION:match(" (.+)$");
+ local lua_path_sep = package.config:sub(3,3);
+ local dir_sep = package.config:sub(1,1);
+ local sub_path = dir_sep.."lua"..dir_sep..lua_version..dir_sep;
+ if not string.match(package.path, installer_plugin_path) then
+ package.path = package.path..lua_path_sep..installer_plugin_path..dir_sep.."share"..sub_path.."?.lua";
+ package.path = package.path..lua_path_sep..installer_plugin_path..dir_sep.."share"..sub_path.."?"..dir_sep.."init.lua";
+ end
+ if not string.match(package.path, installer_plugin_path) then
+ package.cpath = package.cpath..lua_path_sep..installer_plugin_path..dir_sep.."lib"..sub_path.."?.so";
+ end
+end
+
return path_util;
diff --git a/util/pluginloader.lua b/util/pluginloader.lua
index 9ab8f245..af0428c4 100644
--- a/util/pluginloader.lua
+++ b/util/pluginloader.lua
@@ -36,12 +36,13 @@ end
local function load_resource(plugin, resource)
resource = resource or "mod_"..plugin..".lua";
-
+ local lua_version = _VERSION:match(" (.+)$");
local names = {
"mod_"..plugin..dir_sep..plugin..dir_sep..resource; -- mod_hello/hello/mod_hello.lua
"mod_"..plugin..dir_sep..resource; -- mod_hello/mod_hello.lua
plugin..dir_sep..resource; -- hello/mod_hello.lua
resource; -- mod_hello.lua
+ "share"..dir_sep.."lua"..dir_sep..lua_version..dir_sep.."mod_"..plugin..dir_sep..resource;
};
return load_file(names);
diff --git a/util/prosodyctl.lua b/util/prosodyctl.lua
index 9b627bde..163658f3 100644
--- a/util/prosodyctl.lua
+++ b/util/prosodyctl.lua
@@ -39,6 +39,16 @@ local function show_usage(usage, desc)
end
end
+local function show_module_configuration_help(mod_name)
+ print("Done.")
+ print("If you installed a prosody plugin, don't forget to add its name under the 'modules_enabled' section inside your configuration file.")
+ print("Depending on the module, there might be further configuration steps required.")
+ print("")
+ print("More info about: ")
+ print(" modules_enabled: https://prosody.im/doc/modules_enabled")
+ print(" "..mod_name..": https://modules.prosody.im/"..mod_name..".html")
+end
+
local function getchar(n)
local stty_ret = os.execute("stty raw -echo 2>/dev/null");
local ok, char;
@@ -278,10 +288,36 @@ local function reload()
return true;
end
+local function get_path_custom_plugins(plugin_paths)
+ -- I'm considering that the custom plugins' path is the first one at prosody.paths.plugins
+ -- luacheck: ignore 512
+ for path in plugin_paths:gmatch("[^;]+") do
+ return path;
+ end
+end
+
+local function call_luarocks(mod, operation)
+ local dir = get_path_custom_plugins(prosody.paths.plugins);
+ if operation == "install" then
+ show_message("Installing %s at %s", mod, dir);
+ elseif operation == "remove" then
+ show_message("Removing %s from %s", mod, dir);
+ end
+ if operation == "list" then
+ os.execute("luarocks list --tree='"..dir.."'")
+ else
+ os.execute("luarocks --tree='"..dir.."' --server='http://localhost/' "..operation.." "..mod);
+ end
+ if operation == "install" then
+ show_module_configuration_help(mod);
+ end
+end
+
return {
show_message = show_message;
show_warning = show_message;
show_usage = show_usage;
+ show_module_configuration_help = show_module_configuration_help;
getchar = getchar;
getline = getline;
getpass = getpass;
@@ -297,4 +333,6 @@ return {
start = start;
stop = stop;
reload = reload;
+ get_path_custom_plugins = get_path_custom_plugins;
+ call_luarocks = call_luarocks;
};
diff --git a/util/startup.lua b/util/startup.lua
index ab595526..580410c9 100644
--- a/util/startup.lua
+++ b/util/startup.lua
@@ -227,13 +227,19 @@ end
function startup.setup_plugindir()
local custom_plugin_paths = config.get("*", "plugin_paths");
+ local installer_plugin_path = config.get("*", "installer_plugin_path") or "custom_plugins";
+ local path_sep = package.config:sub(3,3);
+ installer_plugin_path = config.resolve_relative_path(require "lfs".currentdir(), installer_plugin_path);
+ require "lfs".mkdir(installer_plugin_path);
+ require"util.paths".complement_lua_path(installer_plugin_path);
if custom_plugin_paths then
- local path_sep = package.config:sub(3,3);
-- path1;path2;path3;defaultpath...
-- luacheck: ignore 111
CFG_PLUGINDIR = table.concat(custom_plugin_paths, path_sep)..path_sep..(CFG_PLUGINDIR or "plugins");
prosody.paths.plugins = CFG_PLUGINDIR;
end
+ CFG_PLUGINDIR = installer_plugin_path..path_sep..(CFG_PLUGINDIR or "plugins");
+ prosody.paths.plugins = CFG_PLUGINDIR;
end
function startup.chdir()