How to migrate trac MySQL-based project from trac 1.0.12 to trac 0.11.7

In a world dominated by JIRA, some still dare to use trac… Here’s how to migrate trac to an earlier version, assuming this was a good idea, which of course it is not!

Versions

On my Ubuntu 16 installation (let’s call it example1.com) I have a project on this version of trac:

$ lsb_release  -d
Description:    Ubuntu 16.10
$ tracd --version
tracd 1.0.12

I had good(-ish) reasons to migrate the entire project to a copy on an Ubuntu 10 machine.

$ lsb_release -d
Description:    Ubuntu 10.04.4 LTS

Installing trac

These are the resources that you need to be aware of:

I first installed trac via the old-releases.ubuntu.com repository.

$ sudo apt-get install trac

This installed an earlier version that the one I had.

$ tracd --version
tracd 0.11.7

Setting up the new (old) trac

Rather than upgrading the entire system with do-release-upgrade, I decided to work with this version.

You will need the python-mysqldb module on example2.com to access a MySQL database. If you’re using PostgreSQL the procedure should be similar. YMMV.

$ sudo apt-get install python-mysqldb

First, copy the assets of the project environment. This is a directory tree that you can copy over using rsync.

rsync -r example1.com:/path-to-trac-env example2.com:/path-to-trac-env

For simplicity we’ll keep everything the same: file directories, database name and database credentials, although you could change these. Your database settings are in the /path-to-trac-env/conf/trac.ini file. You want the database variable under the [trac] section, which should look something like:

[trac]

database = mysql://tracuser:tracpassword@localhost:3306/trac-env

You will want to create an empty MySQL database where your project will live. You will need the MySQL client on example2.com, so if you don’t have it, install it with:

sudo apt-get install mysql-client

You will then want to login as root

mysql -u root -p

and create the database, (using the utf8_bin collation)

CREATE DATABASE `trac-env` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;

and finally create the user:

GRANT ALL ON `trac-env`.* TO tracuser@localhost IDENTIFIED BY 'tracpassword';

Exit the MySQL client with Ctrl-D and import a standard SQL dump of your database from example1.com. For instance, if you like one-liners, you might do this on example2.com:

ssh example1.com "mysqldump -u tracuser -ptracpassword --single-transaction trac-env | gzip -9" | zcat | mysql -u tracuser -ptracpassword trac-env

Nasty hack FTW

Now start tracd and visit the installation via your web browser. You should see an error like this:

 Trac detected an internal error:

ValueError: timestamp out of range for platform time_t

This is because all timestamps in this newer version of trac are in microseconds, rather than seconds. Here is a (somewhat) relevant ticket.

I went ahead and hacked the DB thusly:

update ignore attachment set time = floor( time / 10000000);
update ignore auth_cookie set time = floor( time / 10000000);
update ignore revision set time = floor( time / 10000000);
update ignore ticket set time = floor( time / 10000000);
update ignore ticket set changetime = floor( changetime / 10000000);
update ignore ticket_change set time = floor( time / 10000000);
update ignore version set time = floor( time / 10000000);
update ignore wiki set time = floor( time / 10000000);

These are all the timestamp columns in the DB. Dividing by a million converts millionths of a second to seconds and the floor function makes sure that the result is still an integer.

The ignore argument is there only because I had one single collision in one ticket comment. Needless to say, this is a nasty hack, so don’t rely on it too much.

But, for my purposes, “It Works™”!

Leave a Reply

Your email address will not be published. Required fields are marked *