Pythian Blog: Technical Track

Interesting happenstance when installing Ansible dependencies in a MySQL Docker container

I’ve been posting quite a bit about Docker as I’ve been working with it a lot as of late. I thought I would share something interesting I discovered a couple weeks ago while working on setting up a Docker container-based lab environment for training purposes here at Pythian, specifically when attempting to install the MySQL-python package inside the container. I know what you’re thinking: why is he trying to install a package in a Docker container? Doesn’t that go against the “Docker run and forget about it” philosophy? Sure, but in this case, I’m looking to add orchestration via ansible, which I don’t think is completely out of the question in order to coordinate your Docker containers for something like replication. This requires using the ansible mysql_replication module, which clearly states that MySQL-python is required. I digress. Back to the story. I run the mysql/mysql-server:5.7 docker image from docker hub, which is from the Oracle MySQL team and based on Oracle Linux. Then I attempted to install MySQL-python. Here was my output:
[vagrant@control nopkrbr]$ docker exec -e COLUMNS="`tput cols`" -e LINES="`tput lines`" -ti mysql1 /bin/bash
 bash-4.2# yum install MySQL-python
 Loaded plugins: ovl
 ol7_UEKR4 | 1.2 kB 00:00
 ol7_latest | 1.4 kB 00:00
 (1/5): ol7_UEKR4/x86_64/updateinfo | 194 kB 00:00
 (2/5): ol7_latest/x86_64/group | 659 kB 00:00
 (3/5): ol7_latest/x86_64/updateinfo | 1.8 MB 00:00
 (4/5): ol7_latest/x86_64/primary | 18 MB 00:03
 (5/5): ol7_UEKR4/x86_64/primary | 38 MB 00:06
 ol7_UEKR4 704/704
 ol7_latest 26654/26654
 Resolving Dependencies
 --> Running transaction check
 ---> Package MySQL-python.x86_64 0:1.2.5-1.el7 will be installed
 --> Processing Dependency: libmysqlclient.so.18(libmysqlclient_18)(64bit) for package: MySQL-python-1.2.5-1.el7.x86_64
 --> Processing Dependency: libmysqlclient.so.18()(64bit) for package: MySQL-python-1.2.5-1.el7.x86_64
 --> Running transaction check
 ---> Package mariadb-libs.x86_64 1:5.5.56-2.el7 will be installed
 --> Finished Dependency Resolution
 
 Dependencies Resolved
 
 ================================================================================
 Package Arch Version Repository Size
 ================================================================================
 Installing:
 MySQL-python x86_64 1.2.5-1.el7 ol7_latest 89 k
 Installing for dependencies:
 mariadb-libs x86_64 1:5.5.56-2.el7 ol7_latest 757 k
 
 Transaction Summary
 ================================================================================
 Install 1 Package (+1 Dependent package)
 
 Total download size: 846 k
 Installed size: 4.7 M
 Is this ok [y/d/N]: y
 Downloading packages:
 (1/2): MySQL-python-1.2.5-1.el7.x86_64.rpm | 89 kB 00:00
 (2/2): mariadb-libs-5.5.56-2.el7.x86_64.rpm | 757 kB 00:00
 --------------------------------------------------------------------------------
 Total 1.4 MB/s | 846 kB 00:00
 Running transaction check
 Running transaction test
 
 Transaction check error:
 file /etc/my.cnf from install of mariadb-libs-1:5.5.56-2.el7.x86_64 conflicts with file from package mysql-community-server-minimal-5.7.22-1.el7.x86_64
 file /usr/share/mysql/charsets/Index.xml from install of mariadb-libs-1:5.5.56-2.el7.x86_64 conflicts with file from package mysql-community-server-minimal-5.7.22-1.el7.x86_64
 file /usr/share/mysql/charsets/armscii8.xml from install of mariadb-libs-1:5.5.56-2.el7.x86_64 conflicts with file from package mysql-community-server-minimal-5.7.22-1.el7.x86_64
 file /usr/share/mysql/charsets/ascii.xml from install of mariadb-libs-1:5.5.56-2.el7.x86_64 conflicts with file from package mysql-community-server-minimal-5.7.22-1.el7.x86_64
 file /usr/share/mysql/charsets/cp1250.xml from install of mariadb-libs-1:5.5.56-2.el7.x86_64 conflicts with file from package mysql-community-server-minimal-5.7.22-1.el7.x86_64
 file /usr/share/mysql/charsets/cp1256.xml from install of mariadb-libs-1:5.5.56-2.el7.x86_64 conflicts with file from package mysql-community-server-minimal-5.7.22-1.el7.x86_64
And so on. When I saw this I couldn’t help but chuckle at the fact that the dependency to have lib (or libs-compat) on the system in order to install MySQL-python was resolved by using the default repo… in the MySQL community-issued Docker image… using Oracle Linux… which uses MariaDB. This really wasn’t a big deal in this case. I was able to get around the issue by adding a few extra tasks to my playbook, as listed below.
---
 - name: "Install mysql yum repository"
  yum:
  name: https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm
  state: present
 
 - name: "Enable all versions in MySQL yum repository"
  replace:
  path: /etc/yum.repos.d/mysql-community.repo
  regexp: '^enabled=0$'
  replace: 'enabled=1'
 
 - name: "Install mysql compatible libraries. Required to install Python MySQL package"
  yum:
  disablerepo: "*"
  enablerepo: "mysql-community"
  name: mysql-community-libs-compat
  state: present
 
 - name: "Install MySQL Python Module"
  yum:
  name: MySQL-python
  state: present
What’s happening here is that I’m installing the mysql yum repository in the first task so I can get packages from the Oracle MySQL project instead of from the default repo which uses MariaDB. This creates the /etc/yum.repos.d/mysql-community.repo which allows you to enable and disable MySQL repositories based on major version. The second task marks all repositories in the /etc/yum.repos.d/mysql-community.repo file as enabled, so any of them can be used. The third task installs the latest minor version of mysql-community-libs-compat based on the major version of MySQL that I have running in my container. There is a reference here to a variable ‘mysql_version_no_periods’ which is populated in an earlier playbook with the major version of MySQL that is running in the container, but with the decimals removed. So, in this case, that value of the variable is ‘57’. This task is using this variable to disable all repositories in yum with the exception of the repository for the specific major version that I’m using, thus ensuring that when this task runs, I’ll always get the latest minor version of the mysql-community-libs-compat package for the major version of MySQL that’s running in my container. Finally, now that my dependency is installed, the fourth and final task installs MySQL-python so I can use ansible to work with the MySQL instance running in my Docker container.

Conclusion

Recently, MariaDB has become a default package when attempting to use package managers for MySQL installation on various Linux distributions, so it’s easy to see how something like this could have slipped through the cracks. When you take everything into consideration about the Docker image that has been made available by the Oracle MySQL team, this is really only a very small setback for an otherwise great resource. You could even argue that this really isn’t an issue considering the Docker philosophy. However, I do believe that process orchestration via automation tools like Chef, Puppet and Ansible aren’t going to be out of the question for Docker deployments. So I think it would be worth it to ensure that dependencies like this can be more easily resolved by making sure the repositories in use are compatible with the MySQL fork that’s installed on the image.

No Comments Yet

Let us know what you think

Subscribe by email