view mod_migrate/mod_migrate.lua @ 3965:2b10e51d85a6

mod_muc_limits: Add config option to limit to join stanzas only This is a bit more limited in pre-0.11 MUC modules, because it just detects stanzas sent to full JIDs (which would include all presence and nick changes). This option is useful for setups where users are typically unaffiliated, but trusted (e.g. if access to the room is gated through some other means such as password/token auth).
author Matthew Wild <mwild1@gmail.com>
date Fri, 03 Apr 2020 12:26:56 +0100
parents 611ac62c5b63
children c9e1eee6a948
line wrap: on
line source

-- mod_migrate

local unpack = table.unpack or unpack;
local sm = require"core.storagemanager";
local um = require"core.usermanager";

local function users(store, host)
	if store.users then
		return store:users();
	else
		return um.users(host);
	end
end

function module.command(arg)
	local host, source_stores, migrate_to = unpack(arg);
	if not migrate_to then
		return print("Usage: prosodyctl mod_migrate example.com <source-store>[-<store-type>] <target-driver> [users]*");
	end
	if not prosody.hosts[host] then
		return print(("The host %q is not know by Prosody."):format(host));
	end
	sm.initialize_host(host);
	um.initialize_host(host);
	local module = module:context(host);
	for source_store in source_stores:gmatch("[^,]+") do
		local store_type = source_store:match("%-(%a+)$");
		if store_type then
			source_store = source_store:sub(1, -2-#store_type);
		end
		local storage = module:open_store(source_store, store_type);
		local target = assert(sm.load_driver(host, migrate_to));
		target = assert(target:open(source_store, store_type));

		local function migrate_user(username)
			module:log("info", "Migrating %s data for %s", source_store, username);
			local data, err = storage:get(username);
			if not data and err then
				module:log("error", "Could not read data: %s", err);
			else
				local ok, err = target:set(username, data);
				if not ok then
					module:log("error", "Could not write data: %s", err);
				end
			end
		end

		if store_type == "archive" then
			function migrate_user(username)
				module:log("info", "Migrating %s archive items for %s", source_store, username);
				local count, errs = 0, 0;
				for id, item, when, with in storage:find(username) do
					local ok, err = target:append(username, id, item, when, with);
					if ok then
						count = count + 1;
					else
						module:log("warn", "Error: %s", err);
						errs = errs + 1;
					end
					if ( count + errs ) % 100 == 0 then
						module:log("info", "%d items migrated, %d errors", count, errs);
					end
				end
				module:log("info", "%d items migrated, %d errors", count, errs);
			end
		end

		if arg[4] then
			for i = 4, #arg do
				migrate_user(arg[i]);
			end
		else
			xpcall(function()
				for user in users(storage, host) do
					migrate_user(user);
				end
			end,
			function (err)
				module:log("error", "Could not list users, you'll have to supply them as arguments");
				module:log("error", "The error was: %s", err);
			end);
		end
	end
end