Infiniroot Blog: We sometimes write, too.

Of course we cannot always share details about our work with customers, but nevertheless it is nice to show our technical achievements and share some of our implemented solutions.

How we migrated from ((OTRS)) Community Edition to Znuny LTS

Published on December 29th 2022


At Infiniroot we've been using ((OTRS)) Community Edition (CE) since our earliest days. We needed a (free and preferably open source) software to receive and handle incoming support requests and use the tickets for time accounting. At the end of the month we would run a report and create customer invoices based on summarized logged support time.

After some evaluation period comparing different solutions, we decided to use OTRS as our ticket software. Partly because we've already had some experiences in the past (with OTRS 2.x) but mainly because there was a huge open source community around OTRS, especially in Germany.

Back in 2013 we started with OTRS 3.2.8 and over the years upgraded up to OTRS 6.0.x. 

The end of ((OTRS CE))

In early 2021 the users of the open source variant of OTRS, meanwhile renamed to "((OTRS)) Community Edition" to distinguish between the commercial "OTRS" software, were stunned to learn that the end of ((OTRS Community Edition)) was announced and that future versions would only be made for the commercial variant.

For large companies with $$$ this is not a problem, but for a small company relying on a free to use and stable open source product these news were not good at all.

Over the past few years, there have already been a few forks of ((OTRS)). The latest fork, which jumped in shortly around the EOL announcement, was Znuny.

After keeping this migration project in our backlog for several months, we finally migrated our ((OTRS)) CE to Znuny a couple of weeks ago.

OTRS Community Edition migration to Znuny

Understanding "migration"

The trickiest or even most confusing part of the migration from ((OTRS)) CE to Znuny is to understand, what part must actually be migrated. Or in other words: Is the migration a data migration from ((OTRS)) CE to Znuny? Is it a "overwrite" migration? How should the data be migrated from ((OTRS)) CE to Znuny? These questions are unfortunately not properly answered by the Znuny documentation. One hint could be found in the Znuny 6.1 Update notes:

Please note that your current systems needs to be a ((OTRS)) CE 6.0.x, OTRS 6.0.x or Znuny LTS 6.0.x to perform the update [to Znuny 6.1].

This therefore means: Consider Znuny 6.0.x (LTS) as a minor and Znuny 6.1.x as major upgrade to your existing ((OTRS)) CE 6.0.x release. The word migration is actually confusing when thinking of it this way and should be called "replacement upgrade".

Upgrading ((OTRS)) CE to Znuny 6.1

From the update notes mentioned above we can see that a direct upgrade from ((OTRS)) CE 6.0.x to Znuny 6.1.x is supported. We therefore decided to immediately upgrade to Znuny 6.1. For this purpose we created a new server running Debian Bullseye for Znuny. This is not a requirement though, you could continue to use your existing server. Once the new server for Znuny was ready and prepared, the data was moved from the old OTRS server. To sum up our upgrade tasks:

To prepare the upgrade to Znuny 6.1, stop server processes on the Znuny server:

root@znuny:~# systemctl stop apache2
root@znuny:~# systemctl stop postfix
root@znuny:~# su -c 'bin/Cron.sh stop' - otrs
no crontab for otrs
failed
root@znuny:~# su -c 'bin/otrs.Daemon.pl stop' - otrs
Manage the OTRS daemon process.
Daemon stopped

Download the latest 6.1 release from Znuny:

root@znuny:~# cd /opt/otrs && wget https://download.znuny.org/releases/znuny-latest-6.1.tar.gz

This now leaves us with the following directory structure in /opt/, where /opt/otrs is currently a symlink to the copy of the old OTRS directory (otrs-6.0.28):

root@znuny:/opt# ls -la

total 35424
drwxr-xr-x  3 root root         4096 Dec  8 21:49 .
drwxr-xr-x 18 root root         4096 Nov 21 05:20 ..
lrwxrwxrwx  1 root root           11 Dec  8 21:49 otrs -> otrs-6.0.28
drwxr-xr-x 10 otrs www-data     4096 Jul 15  2021 otrs-6.0.28
-rw-r--r--  1 root root     36258392 Sep 29  2021 znuny-latest-6.1.tar.gz

Unpack the Znuny 6.1 release:

root@znuny:/opt# tar xfz znuny-latest-6.1.tar.gz

This should now have unpacked Znuny into a directory "znuny-6.1.2". The version number could change in the future, but it's rather unlikely (given that 6.1 is not a LTS release and does not receive further updates). Now set the correct permissions using the integrated SetPermissions.pl script:

root@znuny:/opt# /opt/znuny-6.1.2/bin/otrs.SetPermissions.pl
Setting permissions on /opt/znuny-6.1.2

Copy the main configuration file (Kernel/Config.pm) from OTRS to Znuny:

root@znuny:/opt# cp -av /opt/otrs/Kernel/Config.pm /opt/znuny-6.1.2/Kernel/
'/opt/otrs/Kernel/Config.pm' -> '/opt/znuny-6.1.2/Kernel/Config.pm'

The Znuny documentation also mentions moving articles from OTRS to Znuny. In our case the var/article directory was empty:

root@znuny:/opt# mv /opt/otrs/var/article/* /opt/znuny-6.1.2/var/article/
mv: cannot stat '/opt/otrs/var/article/*': No such file or directory

Copy dot files from OTRS to Znuny:

root@znuny:/opt# for f in $(find -L /opt/otrs -maxdepth 1 -type f -name .\* -not -name \*.dist); do cp -av "$f" /opt/znuny-6.1.2/; done
'/opt/otrs/.bash_history' -> '/opt/znuny-6.1.2/.bash_history'
'/opt/otrs/.bash_completion' -> '/opt/znuny-6.1.2/.bash_completion'
'/opt/otrs/.selected_editor' -> '/opt/znuny-6.1.2/.selected_editor'
'/opt/otrs/.viminfo' -> '/opt/znuny-6.1.2/.viminfo'

Copy dot files from OTRS cron to Znuny:

root@znuny:/opt# for f in $(find -L /opt/otrs/var/cron -maxdepth 1 -type f -name .\* -not -name \*.dist); do cp -av "$f" /opt/znuny-6.1.2/var/cron/; done

Remove OTRS symlink (/opt/otrs), replace with new OTRS symlink (/opt/otrs) pointing to /opt/znuny-6.1.2):

root@znuny:/opt# rm /opt/otrs
root@znuny:/opt# ln -s /opt/znuny-6.1.2 /opt/otrs

The directory structure in /opt/ should now look like this with the symlink pointing to the Znuny release:

root@znuny:/opt# ls -la
total 35428
drwxr-xr-x  4 root root         4096 Dec  8 21:53 .
drwxr-xr-x 18 root root         4096 Nov 21 05:20 ..
lrwxrwxrwx  1 root root           16 Dec  8 21:53 otrs -> /opt/znuny-6.1.2
drwxr-xr-x 10 otrs www-data     4096 Jul 15  2021 otrs-6.0.28
drwxr-xr-x  9 otrs www-data     4096 Dec  8 21:53 znuny-6.1.2
-rw-r--r--  1 root root     36258392 Sep 29  2021 znuny-latest-6.1.tar.gz

Run otrs.CheckModules.pl to check for missing Perl modules:

root@znuny:/opt# /opt/otrs/bin/otrs.CheckModules.pl --all

If the server was correctly prepared (as mentioned in the upgrade tasks above) no required Perl modules should be listed. In case there are any required modules missing, install them.

Now run the actual migration script, which migrates ((OTRS)) CE 6.0.x to Znuny 6.1.2. This needs to be run as otrs user:

root@znuny:/opt# su - otrs

otrs@znuny:~$ scripts/MigrateToZnuny6_1.pl
 Migration started ...
 Checking requirements ...

    Requirement check for: Check framework version ...
    Requirement check for: Check required Perl version ...
    Requirement check for: Check required database version ...
    Requirement check for: Check database charset ...
    Requirement check for: Check required Perl modules ...
    Requirement check for: Check if database has been backed up ...

        Did you backup the database? [Y]es/[N]o: Y

    Requirement check for: Upgrade database structure ...

 Executing tasks ...

    Step 1 of 19: Check framework version ...
    Step 2 of 19: Check required Perl version ...
    Step 3 of 19: Check required database version ...
    Step 4 of 19: Check database charset ...
    Step 5 of 19: Check required Perl modules ...
    Step 6 of 19: Check installed CPAN modules for known vulnerabilities ...
    Step 7 of 19: Check if database has been backed up ...
    Step 8 of 19: Upgrade database structure ...
    Step 9 of 19: Rebuild configuration ...
    Step 10 of 19: Migrate SysConfig settings ...
    Step 11 of 19: Initialize default cron jobs ...
    Copying /opt/otrs/var/cron/aaa_base.dist to /opt/otrs/var/cron/aaa_base...
    done.
    Copying /opt/otrs/var/cron/otrs_daemon.dist to /opt/otrs/var/cron/otrs_daemon...
    done.
    Step 12 of 19: Migrate web service configuration ...
    Step 13 of 19: Migrate groups ...
    Step 14 of 19: Uninstall merged packages ...
    Step 15 of 19: Clean up the cache ...
    Step 16 of 19: Rebuild configuration another time ...
    Step 17 of 19: Deploy ACLs ...
    Step 18 of 19: Deploy processes ...
    Step 19 of 19: Check invalid settings ...

 Migration completed!

otrs@znuny:~$ bin/otrs.Console.pl Admin::Package::UpgradeAll
There are no installed packages
Done.

otrs@znuny:~$ exit

Now, again as root user, start the otrs cron service:

root@znuny:/opt# su -c 'bin/Cron.sh start' - otrs
(using /opt/znuny-6.1.2) done

Start the server processes:

root@znuny:/opt# systemctl start apache2
root@znuny:/opt# systemctl start postfix

That's it. After a few minutes you should be able to see the otrs daemon processes running. Do not start them manually, let the otrs cron job do this for you.

Hello Znuny!

Now that the "migration" (or rather upgrade) to Znuny was completed, we could access the same domain (after pointing it to the new Znuny server) and immediately saw the Znuny login prompt. After logging in with our existing credentials, we recognized the familiar dashboard user interface. Only the large Znuny logo (top right) shows a visual difference compared to the old ((OTRS)) CE installation. And most importantly: All our tickets (open and closed) exist, (monthly) reports are still working and new tickets creation (through e-mail) works!

Znuny dashboard after migration from ((OTRS)) CE