How do I handle all those MySQLs

In openSUSE we’ve got currently MySQL Community Server, MariaDB and MySQL Cluster. From all of these we have even multiple versions. Although these packages are different, they are quilte similar. So I’m handling them in a little bit special way.
When I was adding MariaDB I knew that packaging will be quite similar to the MySQL Community Server. So I took some parts of .spec file away into separate files so I can sync them easily and left only package dependent parts in .spec files. Later on, I created special git repository and few scripts to handle patches and patch sharing among these variants. And lately I automatized tre rest of the manual syncing I was diong. So today I want to present how do I do MySQL packaging today. And that is also some tutorial on how you can modify these packages easily or even create packages for other variants like Percona 😉
Everything starts with one of my repositories on github. Let’s take a look at what it contains. Some scripts and few directories. Let’s start with directories.
First directory is named common and it contains several files. As you can guess, it contains code common to all MySQL variants. So you can find here build scripts, install scripts, rc script, few readmes and template for the spec file. Templates ends up with .in. All non-template files are later committed to the openSUSE Build Service as they are in the repository. Templates needs to be filled in first. For that I decided to use mustache. You can install it by running gem install mustache. But back to the packaging. We need some variant specific files, something to fill templates with and some patches, right?
For these reasons there are directories named after particular MySQL variant (for example mysql-community-server-56 or mariadb-53). Inside these directories are at least config.yaml file and series fil. But probably there is some more. config.yaml file is used by mustache to fill in the templates. So you can find here package names, descriptions, versions and such. Things that has to differ among all variants.
Apart from these, you can also find some .cnf files in variant specific directories. These are configuration files to be included. This way even if you modify your /etc/my.cnf, these snippets can get updated (if you don’t modify them as well). Here is also place for some contribution – you can send me just few snippets from my.cnf, that will improve default configuration 😉 Or create packages with new plugins and them register automatically here.
Last file in the variant directory I spoke about – series file and the last directory I havn’t spoke about yet – patches have something in common – they are used for patching. series file contains a list of patches to apply. And patches directory contains these patches. How it works is described in my other github repository. Basically the point is to use few scripts so I have to maintain just series file outside of .spec file. Then there are scripts that will fetch patches, pack them up and during build apply them. No need for me to take some extra care.

Example

So how it works in practice. Let’s imagine we want to update MariaDB 5.3.x to newer version. I will go to the local checkout of mariadb-53 package (how to get one was described in the first article of this series) and replace old tarball with new one. Then I will modify mariadb-53/config.yaml file in packaging repository (change the version). After that I will call the only thing I haven’t spoke about yet – update-package.sh script in my packaging repository. This will check current path and according to the directory I’m in it will pick correct variant and replace all files with updated variants from the repository – new rc script, updated .spec file and everything. After that I need to check whether all patches still apply or fix them (now quilt comes handy) and try building the package. It may happen that I’ll find something that needs to be fixed. In that case, I’ll fix stuff in the git repository and let the script recreate everything. When I’m finished, I’ll commit everything to obs and git and move to another package. The key is that this way although I’m maintaining a lot of MySQL variants, I maintain them all as one. An if I fix something in one variant, fixes will eventually get to all of them 😉