--- a/mod_migrate/README.markdown Tue Sep 01 10:30:08 2015 +0200
+++ b/mod_migrate/README.markdown Tue Sep 01 10:59:43 2015 +0200
@@ -1,5 +1,4 @@
---
-labels:
summary: prosodyctl cross storage driver migration tool
...
@@ -10,20 +9,37 @@
storage drivers.
Usage:
-`prosodyctl mod_migrate example.com <source-store> <target-driver> [users]*`
+
+ Usage: prosodyctl mod_migrate example.com <source-store>[-<store-type>] <target-driver> [users]*
-`<source-store>` would be e.g. `accounts` or `private`
+`<source-store>` would be e.g. `accounts` or `private`. To migrate
+archives, the optional suffix `<store-type>` would be set to `archive`,
+so e.g. `archive2-archive` or `muc_log-archive`.
`<target-driver>` is the storage driver to copy data to, sans the
`mod_storage_` prefix.
The process is something like this:
-1. Decide on the future configuration and add this to your prosody
- config.
+1. Decide on the future configuration and add for example SQL
+ connection details to your prosody config, but don't change the
+ `store` option yet.
2. With Prosody shut down, run
`prosodyctl mod_migrate example.com accounts sql`
3. Repeat for each store, substituting 'accounts'. E.g. vcards,
private...
-4. Change the `storage` configuration to use the new driver.
+4. Change the [`storage` configuration](https://prosody.im/doc/storage)
+ to use the new driver.
5. Start prosody again.
+
+Examples
+========
+
+ for store in accounts roster private blocklist vcard archive2-archive; do
+ prosodyctl migrate example.com $store sql2
+ done
+
+Compatibility
+=============
+
+Should work with 0.8 and later.
--- a/mod_migrate/mod_migrate.lua Tue Sep 01 10:30:08 2015 +0200
+++ b/mod_migrate/mod_migrate.lua Tue Sep 01 10:59:43 2015 +0200
@@ -7,14 +7,19 @@
function module.command(arg)
local host, source_store, migrate_to, user = unpack(arg);
if not migrate_to then
- return print("Usage: prosodyctl mod_migrate example.com <source-store> <target-driver> [users]*");
+ return print("Usage: prosodyctl mod_migrate example.com <source-store>[-<store-type>] <target-driver> [users]*");
end
sm.initialize_host(host);
um.initialize_host(host);
local module = module:context(host);
- local storage = module:open_store(source_store);
+ 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));
+ target = assert(target:open(source_store, store_type));
+
local function migrate_user(username)
module:log("info", "Migrating data for %s", username);
local data, err = storage:get(username);
@@ -22,6 +27,26 @@
assert(target:set(username, data));
end
+ if store_type == "archive" then
+ function migrate_user(username)
+ module:log("info", "Migrating archive items for %s", 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]);