When JIT connects to Jabberd 1.4 using Jabberd 1.4's XDB support, it puts the spool in a certain format.
When JIT connects to Jabberd 2.0 the spool is in a completely different format, adding new subdirectories all over the place, presumably as some form of hashing.
So how is no migration required?
[2004-03-16 08:20 CST] Maqi If you look at JIT's docs, you see that the scenario 1 you described (JIT runs in WPJabber, WPJabber connects to jabberd14 and uses its XDB services) is *not* covered. You can of course configure your setup this way and it works, however, the standard way is to let WPJabber's xdb_file handle XDB (which is unrelated to the main jabberd's XDB then).
I don't know what you mean with scenario 2. Jabberd2 does not handle XDB at all AFAIK so letting JIT connect to jabberd2 without configuring the WPJabber JIT runs in to handle XDB will fail. If you configure WPJabber to handle XDB, nothing changes from the jabberd14 setup though.
And, just for the record, jabberd 1.4.2 and 1.4.3 use a "flat" directory structure for XDB. jabberd14 (CVS) and WPJabber both use subdirectories (see jabberd14 CVS commit logs for details) as this improves speed a lot with many users and "old" filesystems such as ext2 without htree extensions (handling large directories is very slow then).
[2004-03-19 12:06 CST] Maqi As I reread your post, I think I understand. You seem to refer to WPJabber's (new) spool format, this is not really related to jabberd2. If a jabberd1.4.2/1.4.3 spool directory (for JIT) shall be handled by WPJabber's XDB component, you need to convert it before. There's a tool included in WPJabber to do this. jabberd14 (CVS) which uses the same spool format as WPJabber even migrates transparently and automatically.
The whole topic is bit confusing I fear ;-).
[2004-04-08 13:47 CDT] Sean (email) fyi, this script doesn't work with Ruby 1.6.4. Using the 1.8.1 works fine, however. Cool script!
[2004-04-10 01:37 CDT] Sean (email) err, there's a problem I didn't notice earlier. Running the script yields this:
/usr/local/ruby-1.8.1/lib/ruby/site_ruby/1.8/rexml/parsers/baseparser.rb:291:in `pull': Missing end tag for 'query' (got "xdb") (REXML::ParseException) Line: 6 Position: 2795 Last 80 unconsumed characters: from /usr/local/ruby-1.8.1/lib/ruby/site_ruby/1.8/rexml/document.rb:180:in `build' from /usr/local/ruby-1.8.1/lib/ruby/site_ruby/1.8/rexml/document.rb:44:in `initialize' from /home/sean/migrate_tx:66:in `new' from /home/sean/migrate_tx:66 from /home/sean/migrate_tx:53:in `foreach' from /home/sean/migrate_tx:53
I'm not versed in ruby...a little help?
[2004-12-19 16:24 CST] trejkaz (email) Just so people know, my contact JID is soon changing:
trejkaz@jabber.zim.net.au
#!/usr/bin/ruby
#
# Migration script for jabberd1.4 to jabberd2.
#
# Copyright (c) 2004 Trejkaz Xaoza
#
# This Ruby script converts a jabberd1.4 spool directory into a Mysql script for jabberd2.
# The reason it doesn't directly use Mysql to insert the data is so that the result can be
# confirmed to work before the script is run. Additionally, I have no access to Ruby on the
# server my Jabber service runs on. The reason it doesn't use Perl is I was dissatisfied
# with Perl's support for XML namespaces.
#
# What it does do:
# * Converts all possible data from a single spool directory into a Mysql script.
# * Yes, that includes offline messages and VCard, neither of which jabberd2's tools/migrate.pl can do.
# * Makes your users happier because you don't wipe their offline messages. Can't stress this enough. ;-)
#
# What doesn't it do:
# * It doesn't work with Postgresql or db4 storage types. In the case of Postgresql this might
# not be too hard to fix. In fact the quoting character is probably the only difference between
# Mysql and Postgresql for this purpose.
# * It doesn't update the database directly.
# * It doesn't migrate the transports. Note that JIT, since it uses a different jabberd and more
# importantly a different xdb_file module, has a spool format which is different to all the other
# components' spools, and incompatible with the JIT spool saved by jabberd1.4. This means you still
# have to migrate the JIT spool separately. It would be nice if someone would contribute a script
# to do this actually.
# * It doesn't cook toast, etc.
#
# Contact details:
# Email: trejkaz@xaoza.net
# Jabber: trejkaz@jabber.xaoza.net
#
# Revision history:
# 0.3 - Check for null passwords and insert empty strings in this case.
# 0.2 - Fixed authreg realm values. Make entries into the active table to prevent some login failures.
# 0.1 - Original version
#
require "rexml/document"
require "mysql"
if not ARGV[0] then
$stderr.puts("ERROR: You must specify the realm (server id) to use.")
Kernel.exit(1)
end
realm = ARGV[0]
if not File.stat(realm).directory? then
$stderr.puts("ERROR: You must be in the spool directory.")
Kernel.exit(1)
end
Dir.foreach(realm) do |filename|
username = filename.clone;
username.gsub!(/\.xml$/, '')
owner = username + "@" + realm
filename = realm + "/" + filename
if not File.stat(filename).directory? then
$stderr.puts "Processing #{owner}..."
puts "INSERT INTO authreg (username, realm) VALUES ('#{Mysql.escape_string(username)}', '#{Mysql.escape_string(realm)}');"
puts "INSERT INTO active (`collection-owner`) VALUES ('#{Mysql.escape_string(owner)}');"
file = File.new(filename)
doc = REXML::Document.new(file)
doc.root.elements.each do |element|
qname = element.name
if element.namespace != nil then
qname = element.namespace + " " + qname
end
case qname
when "jabber:iq:auth:0k zerok"
puts "UPDATE authreg SET hash = '#{element.elements["hash"].text}', token = '#{element.elements["token"].text}', " +
"sequence = #{element.elements["sequence"].text} WHERE username = '#{Mysql.escape_string(username)}' AND realm = '#{Mysql.escape_string(realm)}';"
when "jabber:iq:auth password"
puts "UPDATE authreg SET `password` = '#{Mysql.escape_string(element.text.nil? ? '' : element.text)}' " +
"WHERE username = '#{Mysql.escape_string(username)}' AND realm = '#{Mysql.escape_string(realm)}';"
when "jabber:iq:last query"
puts "INSERT INTO logout (`collection-owner`, time) VALUES ('#{Mysql.escape_string(owner)}', #{element.attributes["last"]});"
when "jabber:iq:roster query"
element.elements.each("item") do |item|
item_subscription = item.attributes["subscription"]
if (item_subscription == "to" || item_subscription == "both") then
item_to = 1
else
item_to = 0
end
if (item_subscription == "from" || item_subscription == "both") then
item_from = 1
else
item_from = 0
end
if (item.attributes["ask"] == "subscribe") then
item_ask = 1
else
# Note: item_ask = 2 isn't possible since jabberd 1.4 doesn't store pending unsubscribe state.
item_ask = 0
end
item_jid = item.attributes["jid"]
item_name = item.attributes["name"]
if item_name then
puts "INSERT INTO `roster-items` (`collection-owner`, jid, name, `to`, `from`, ask) " +
"VALUES ('#{Mysql.escape_string(owner)}', '#{Mysql.escape_string(item_jid)}', '#{Mysql.escape_string(item_name)}', " +
"#{item_to.to_s}, #{item_from.to_s}, #{item_ask.to_s});"
else
puts "INSERT INTO `roster-items` (`collection-owner`, jid, `to`, `from`, ask) " +
"VALUES ('#{Mysql.escape_string(owner)}', '#{Mysql.escape_string(item_jid)}', " +
"#{item_to.to_s}, #{item_from.to_s}, #{item_ask.to_s});"
end
item.elements.each("group") do |group|
if (group.text) then
puts "INSERT INTO `roster-groups` (`collection-owner`, jid, `group`) " +
"VALUES ('#{Mysql.escape_string(owner)}', '#{Mysql.escape_string(item_jid)}', '#{Mysql.escape_string(group.text)}');";
end
end
end
when "jabber:x:offline foo"
element.elements.each("message") do |message|
puts "INSERT INTO queue (`collection-owner`, `xml`) VALUES ('#{Mysql.escape_string(owner)}', '#{Mysql.escape_string(message.to_s)}');"
end
when "vcard-temp vCard", "vcard-temp vcard" # typo
puts "INSERT INTO vcard (`collection-owner`) VALUES ('#{Mysql.escape_string(owner)}');"
def vcard_iter
yield "fn", "FN"
yield "nickname", "NICKNAME"
yield "url", "URL"
yield "tel", "TEL/NUMBER"
yield "email", "EMAIL[USERID]/USERID"
yield "title", "TITLE"
yield "role", "ROLE"
yield "bday", "BDAY"
yield "desc", "DESC"
yield "n-given", "N/GIVEN"
yield "n-family", "N/FAMILY"
yield "adr-street", "ADR/STREET"
yield "adr-extadd", "ADR/EXTADD"
yield "adr-locality", "ADR/LOCALITY"
yield "adr-region", "ADR/REGION"
yield "adr-pcode", "ADR/PCODE"
yield "adr-country", "ADR/COUNTRY"
yield "org-orgname", "ORG/ORGNAME"
yield "org-orgunit", "ORG/ORGUNIT"
end
vcard_iter { |vcard_table_field, vcard_xpath|
vcard_field = element.elements[vcard_xpath]
if (vcard_field and vcard_field.text) then
puts "UPDATE vcard SET `#{vcard_table_field}` = '#{Mysql.escape_string(vcard_field.text)}' " +
"WHERE `collection-owner` = '#{Mysql.escape_string(owner)}';"
end
}
else
if element.attributes["j_private_flag"] == "1" then
puts "INSERT INTO private (`collection-owner`, ns, xml) VALUES ('#{Mysql.escape_string(owner)}', '#{element.namespace}', '#{Mysql.escape_string(element.to_s)}');"
else
# We ignore these because non-private arbitrary storage is out of the question.
end
end
end
end
end
$stderr.puts "Completed processing for #{realm}!"