Upgrading OJS with the ojs_updater
Contents
Introduction
At the University Library Frankfurt, we currently host 21 OJS journals, with more to come. Since we apply a strategy that runs only a single journal within an OJS instance, we have to maintain 21 different OJS instances. In order to maintain and manage this multiplicity, we found it important to come up with structures on the server and helper tools.
Especially the process of updating a journal instance can be quite tedious, since it involves multiple manual steps and can cause problems when forgetting something in the process. Due to these manual steps, the upgrade of a single OJS instance can take up to 20 minutes – and longer, if something doesn’t go according to plan.
To ease the upgrade process of a single OJS instance and make it less error prone, the FID Biodiversity Research and the FID Linguistics developed the ojs_updater tool. This tool is essentially a wrapper around the tools/upgrade.php
script shipped with OJS that automates all the previously manual tasks, performs checks, creates backups before the upgrade (and rewinds in case of an error in the upgrade process) and gives you some additional customisation options. The tool shrinks down the time for an upgrade to 2 to 3 minutes (the actual time for running the process). It automates 7 of the 12 recommended steps of the official PKP guideline for OJS upgrades.
So, what does the ojs_updater
not do?
- It does not activate the maintenance mode automatically. There are too many possibilities and technologies out there to cover them all with this simple tool.
- You should test the upgrade in a sandbox for yourself. Not only, if the upgrade runs successfully, but also make sure that all your plugins and styles are still working as intended.
- You should also have the version to upgrade to available on your system. For this purpose, we have a separate script running that checks every night for new OJS releases and downloads them.
Additionally, the ojs_updater
also does not handle Docker environments. Instead, it expects you to have all your journals in separate folders in the same directory (see next section)
But despite these things, the ojs_updater
got you covered.
This blog post is accompanied by a git repo that includes some of the code examples shown in the text as well as some helper scripts.
Server-side Setup
Requirements
Preparations
You will need the virtual environment package for your Python 3 instance. Under Ubuntu, you would install it with: apt install python3-venv
System Setup
The ojs updater
is actively tested on SUSE Linux Enterprise Server (SLES) and Ubuntu and is known to have worked at some point on other distros/operating systems (e.g. Debian, FreeBSD). However, in order to keep this guide (somewhat) clear, it is assumed that you use Apache 2.4 on Ubuntu 22.10, MariaDB and Python 3.6 or newer. It’s of course possible to use something else; you just need to modify the updater settings accordingly. However, as far as RDBMSes go, only MySQL™ and MariaDB are currently supported. Furthermore, we recommend (and assume) that all your journals are kept in separate folders under the same root directory inside the Apache document root (/usr/www/html/
). This is not required for the ojs_updater
to work, but makes things much easier. Depending on your operating system, the Apache document root can be at different places (/srv/www/…
, /srv/http/…
, /usr/local/www/data/…
, …).
Example:
|
|
In addition to that, it is required to set up a folder structure for the ojs_updater
itself. For the purpose of this tutorial, we assume that you create the folder structure under /usr/local
. Other places are, of course, possible as well.
Example:
|
|
|
|
Now change into the newly created ojs/
folder, create a virtual environment and activate it:
|
|
After making sure you are in fact in the virtual environment, install the ojs_updater
from PyPI:
|
|
Next, we recommend to put a little shell script wrapper in /usr/local/bin/ojs-updater
:
|
|
This allows you to call ojs-updater
directly from the terminal, without the need for activating the virtual environment each time. For convenience, the script is also readily available in the accompanying Github repo of this blog post.
Adapt the script according to your server structure and make it executable with chmod +x /usr/local/bin/ojs-updater
. Next make sure, /usr/local/bin
is in the PATH
variable of root (using your preferred method, e.g. editing /etc/environment
)
Download the OJS Release Package
Let’s assume you want to upgrade an OJS 3.2 instance to OJS 3.3.0-13. First download and extract the necessary OJS version:
|
|
where /usr/ojs/versions/
is the directory, where all potential OJS versions live on your system. The ojs_updater
will always use the most current OJS version in this directory. The tool will never try to download any OJS version! Thus, if the latest OJS version in your /usr/ojs/versions/
is outdated, the ojs_updater
will only upgrade to this outdated version! We recommend to setup a cron job that automatically downloads new OJS versions. An example script for this task is included in the example Github repo.
Configuration
The ojs_updater
expects you to define your system settings once in an ojs_updater_settings.yml
file, where you can set the owner and the group of your OJS instances, the path to the available OJS versions that you can upgrade to, the path to the backup directory, and a list of custom files or directories that have to be copied over during the upgrade process (e.g. themes or custom plugins). All the default migration processes (like copying the public
folder and the config.inc.php
) will be carried out by theojs_updater
without any configuration.
We suggest to start from the example file and modify it according to your local requirements:
|
|
Let’s assume you have a server directory structure like this:
|
|
Hence, you would set the ojs_updater_settings.yml
like this:
|
|
The default setting uses wwwrun
and www
as owner and group of the journal directory, respectively, which is the default Apache user/group on SLES. On Ubuntu, it should be www-data
and www-data
. The ojs_updater
will run permission checks when starting up. If on your system the journal directories are owned by another user, you can also customise this in the ojs_updater_settings.yml
:
|
|
But do not worry. If the ojs_updater
realises that the OJS journal directory is not owned by the expected user, it will just stop and complain. Nothing will break!
You may also see that we decided to set the functions for both mysqldump
and php
explicitly. Normally, you should be fine with just setting the output that is given you by which mysqldump
and which php
. But there may be scenarios (e.g. having multiple PHP versions installed on the same system), where this becomes handy.
The important thing is that you set all this up only once and do not have to think about it with every OJS upgrade you do.
Walk-through
All following steps are required to be run either via sudo
or as the root user. The update script itself can only run as root, but drops its privileges to the specified user/group on start-up. This is usually the Apache user (e.g. www-data
, wwwrun
, …). It also performs a few tests to make sure that no unforeseen permission issues occur during the actual update.
Enter Maintenance Mode
When everything is set up, we can proceed with the actual upgrading process. First, we have to put the journal into maintenance mode. How (or if) you do this, is left to you. This is mostly a precaution. The PKP upgrade guide give a recommendation how to do it on Apache servers.
Run the Upgrade
For the upgrade to start, change to the OJS root directory (/var/www/html/journals
) and call: ojs-updater ./journal-2
.
This will kick-off the upgrade process: checking permissions, creating backups, copying files, and finally starting the actual upgrade script shipped with OJS. The console logs are quite verbose, so you get a clear idea of what is happening.
After the update, you’ll notice that a new folder appeared (journal-2_<timestamp>
) in your journal directory. This is the original folder of the upgraded journal - only renamed. This folder is just kept for convenience, in case something goes wrong. This folder should be removed once you made sure the update was successful.
If the upgrade process should fail after the database migration started (leaving you with an inconsistent database), the ojs_updater
will use the backups it just created to rewind both the database and the journal directory to their original state. We do not recommend to rely on this mechanism, since we could only test it on our own system, but it should still provide you with some safety net. If the automatic rewinding does not work, the ojs_updater
still provides you with the necessary backups to jump back to the last version manually. The backup files are stored at the configured location (default: /usr/local/ojs/backups
.
After the upgrade is completed, the ojs_updater
will terminate. Now you only need to leave maintenance mode and check the config.inc.php.OJSNEW
for any new or deprecated settings. You could do so for example with vimdiff journal-2/config.inc.php journal-2/config.inc.php.OJSNEW
. Please also note, that the ojs_updater
does not upgrade any plugins; these are just carried over if configured. You can upgrade the journal’s plugins in the administration backend after the upgrade.
Forcing an Upgrade
The ojs_updater
will automatically upgrade to the latest version available to it in the directory configured as ojs_version_folder
. If you should try to upgrade an OJS instance that is already on the latest available version, the ojs_updater
will complain and stop safely quite fast. However, should there be a scenario where you need to enforce an OJS update, you can use the --force
parameter.
|
|
This command will update the OJS instance of journal-2 to OJS 3.3.0-13 (which is the latest version in our example version directory /usr/local/ojs/versions/
) even if this exact version is already running in journal-2.
Conclusion
Since its initial development, the ojs_updater
has become a fundamental part of our OJS maintenance workflow, saving us a lot of manual work. We are happy to share our approach and hope that it will prove helpful to others as well. If you decide to try it out and spot some issues, we’d like to encourage you to get in touch via Github issues.
References
All tree diagram created with https://tree.nathanfriend.io
Last Modified on 2022-12-21.