I’ve used the OpenNebula project for several years to run virtual machines to experiment with different Linux distros and software. Unfortunately, they made the decision to continue releasing the main product as Open Source Software but restrict the database migration scripts to non-commercial use  (or require you to pay). This would be fine for my use case but requires submitting an application to be allowed to download the migration scripts, and no-one is going to be responding to my requests over the weekend when I’m looking to upgrade my cluster. Bring on the guerrilla upgrade!
The target database
The software will happily create a fresh database for us and so we’re going to give it an alternative data source to use. I am migrating from a SQLite database to MariaDB here, but you could easily stay with the same data store. Let’s start by stopping the daemon, moving the auth files out the way (facilitates a bootstrapping of the database) and installing MariaDB:
sudo systemctl stop opennebula-sunstone
sudo systemctl stop opennebula
sudo mv /var/lib/one/.one /var/lib/one/.one-backup
sudo apt install mariadb-server-10.3
sudo systemctl enable mariadb
sudo systemctl start mariadb
Once we have a new database server running, we can login as root and create a user for OpenNebula:
CREATE USER 'open_nebula'@'localhost' IDENTIFIED BY 'password123';
CREATE SCHEMA open_nebula;
GRANT ALL PRIVILEGES ON open_nebula.* TO 'open_nebula'@'localhost';
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
Then we can configure OpenNebula by altering
DB = [ BACKEND = "mysql",
SERVER = "localhost",
PORT = 3306,
USER = "open_nebula",
PASSWD = "password123",
DB_NAME = "open_nebula",
CONNECTIONS = 25,
COMPARE_BINARY = "no" ]
Once that’s set, let’s start the daemons:
sudo systemctl start opennebula
sudo systemctl start opennebula-sunstone
This should have created various tables in the MySQL database. Check
/var/log/one/oned.log if those haven’t appeared.
Sketchy data transfer
Once we’ve got a new target database, open both the original and target databases in an editor of your choice. I chose DataGrip as it has great support for both MySQL and SQLite.
We’re now going to go through and copy components from the old database tables
to the new ones. This involves some thought as there are records that will
already exist that we don’t want to overwrite (for example the “oneadmin” user
user_pool table). I had a very simple OpenNebula setup as I just have
one testing host and so here are some of the steps that I had to go through to
reverse engineer the correct data format and to migrate the data manually. More
involved installs will just require paying the money, supporting a great Open
Source (ish) project and accepting that vendors will do weird things to make you
pay for software that is ‘free’. Non-commercial users can request the migration
scripts with a contact form. 2020: what a year, eh?!
I made no changes to this table.
cluster_datastore_relation, cluster_network_relation, cluster_pool
Data copied verbatim.
I made no changes here.
I compared the XML and decided I’d made no changes from the default values so I left these the same.
We don’t want to poison the new database with our old version so I didn’t copy the data across.
I had no documents - good luck!
I didn’t change these from the default so didn’t copy them.
…is meant to be in the past. I just didn’t copy it.
I didn’t use any hooks so left these empty.
Another historic data table that I didn’t use.
I copied the entry and then modified the XML to clear out some fields that are no longer present and to add some new ones. To know what the target XML should look like, I created a new dummy host, inspected its XML (in the “body” column) and then made my old host look like it. Verify that you’ve not hosed it with the CLI:
sudo onehost list
sudo onehost show 0
The schemas in the source code come in very handy for looking at the correct field names.
I didn’t copy this over.
I left the new values untouched and didn’t copy anything.
This was the same in both data stores for me.
I updated the
last_oid value to be the one from the source data store and
added any missing rows. This table is responsible for knowing which ID to give
out to new resources (e.g. virtual machines) as they’re created.
I copied over a user I’d created verbatim. Note that the oneadmin user will have
a new password and it’s located in the
user_quotas, vdc_pool, vm_import
A history table that I left in the past.
Copied verbatim. Where the
lcm_state column was
6, I replaced the
timestamp-like value in the
state column with a
6 as otherwise all of the
deleted VMs appeared in the list. I copied over the full
body column into
short_body and it didn’t explode so that might work for you too.
vm_showback, vmgroup_pool, vn_template_pool, vrouter_pool, zone_pool
Weird and wonderful: the journey to supporting Open Source
It’s a shame that the OpenNebula vendor decided that this was the route they were taking with encouraging users to pay for the software or support it. I’d much rather have the license change (but the migration scripts freely downloadable) or additional modules being created to target enterprise functionality like SSO which aren’t shipped in the community edition. Attempting to upgrade only to be told by the migration CLI that the migrations were missing was a really confusing error. Just link me to the web shop next time. It’s more humane.
What’s your view on publishing community versions of software that you can’t upgrade?
Learning AWS' CDK in TypeScript? Check out my course on Udemy.