How to Prevent Both MySQL and Percona From Being Installed?

80 views
Skip to first unread message

Jon Forrest

unread,
Apr 23, 2014, 4:57:09 PM4/23/14
to puppet-users
I have an interesting problem (to me). I want to install Percona
mysql. This is easy.
But I also want to make sure regular MySQL isn't installed on the same
machine that's running Percona.

To install Percona, I have a resource like

package {
'percona-client':
name => 'Percona-Server-client-55',
ensure => installed,
}

To make sure MySQL isn't installed I have

package {
'mysql':
provider => "yum",
ensure => purged,
}

The problem is that Puppet tries to remove Percona, instead of MySQL.
This is because the Percona rpm provides the mysql feature. By this I mean
the output from 'yum provides mysql' contains (edited):

Percona-Server-client-55-5.5.36-rel34.2.el6.x86_64 : Percona Server - Client
Repo : XXX
Matched from:
Other : mysql

Percona-Server-client-55-5.5.36-rel34.2.el6.x86_64 : Percona Server - Client
Repo : installed
Matched from:
Other : Provides-match: mysql

Of course, trying to remove Percona fails because other things depend on
it, as they should.

The only ideas I have for removing MySQL, and not Percona, are:

1) Use rpmrebuild to change what Percona provides
2) Use something like (untested)

exec { "/usr/bin/yum -y remove mysql":
onlyif => "/bin/rpm -qa |/bin/fgrep mysql"

3) Just presume that MySQL won't be installed in the first place.
I could do this but I'd like my modules to be more accepting and
not require a specially prepared system.

Any suggestions?

Jon Forrest

Jakov Sosic

unread,
Apr 23, 2014, 5:12:15 PM4/23/14
to puppet...@googlegroups.com
On 04/23/2014 10:57 PM, Jon Forrest wrote:
> 3) Just presume that MySQL won't be installed in the first place.
> I could do this but I'd like my modules to be more accepting and
> not require a specially prepared system.
>
> Any suggestions?

You're trying to circuvment the package management problem. I would
suggest you to write custom fact that would check if mysql is installed,
and only then apply ensure => absent for package 'mysql'.

Something along these lines:

Facter.add("mysql_installed") do
setcode do
rpm_mysql = Facter::Util::Resolution.exec('/bin/rpm -qa mysql')
if $rpm_mysql != ''
false
else
true
end
end
end


if ( $::mysql_installed ) {
package { 'mysql': ensure => purged }
}

Adam Backer

unread,
Apr 23, 2014, 5:58:47 PM4/23/14
to puppet...@googlegroups.com, jlfo...@berkeley.edu
John, you left out too many details in how this is implemented.

The require => Class["whatever"] on the percona package, 

and the fact that the Package["mysql"] ensure => absent is INSIDE class 'whatever'

and that it runs successfully the FIRST time, but then is trying to REMOVE percona. 

Please try to require => Package["whatever::mysql"]  directly on the Package["percona-server"] definition, this should not try to re-evaluate the requirement for installing percona-server-server _ONCE IT IS ALREADY INSTALLED_

jcbollinger

unread,
Apr 24, 2014, 11:01:22 AM4/24/14
to puppet...@googlegroups.com


On Wednesday, April 23, 2014 4:12:15 PM UTC-5, Jakov Sosic wrote:
On 04/23/2014 10:57 PM, Jon Forrest wrote:
 > 3) Just presume that MySQL won't be installed in the first place.
> I could do this but I'd like my modules to be more accepting and
> not require a specially prepared system.
>
> Any suggestions?

You're trying to circuvment the package management problem.


I think he's writing very natural and reasonable declarations to express what he's after.  The problem is that there's a bit of a mismatch between Puppet and yum with respect to identifying packages.  Yum primarily identifies packages by their names, but it can also identify packages by the features they provide.  Jon recognizes this.

 
I would
suggest you to write custom fact that would check if mysql is installed,
and only then apply ensure => absent for package 'mysql'.

Something along these lines:

Facter.add("mysql_installed") do
   setcode do
     rpm_mysql = Facter::Util::Resolution.exec('/bin/rpm -qa mysql')
     if $rpm_mysql != ''
       false
     else
       true
     end
   end
end


if ( $::mysql_installed ) {
   package { 'mysql': ensure => purged }
}


For what it's worth, Puppet probably would not exhibit this problem if it were ensuring 'absent' and package mysql was indeed initially absent.  Puppet knows that it doesn't need to act in that case.  Purging is an issue, however, because with some other packaging systems it is possible for a package to be absent but not purged.  The general Package provider infrastructure therefore attempts to purge packages even if they are not installed, and the yum provider does not override that behavior (though it could and should).  Feel free to vote up the relevant bug report: https://tickets.puppetlabs.com/browse/PUP-1198.

Anyway, a custom fact may indeed yield the best workaround.  If it is possible for mysql and percona-client to be installed at the same time, however, then something a bit more involved may be required, because in that case ensuring mysql purged likely removes percona-client as well.  Worse, because percona-client was installed at the beginning of the Puppet run, Puppet will not even realize that it needs to be reinstalled.  (Score another raspberry for 'purged'.)

Ideally, then, it would be best if the percona-client package precluded concurrent installation with mysql.  It may be that a suitable Conflicts: header would serve that purpose, though I'm not sure whether a package is installable or updatable if it conflicts with a feature that it provides itself.  An Obsoletes: header might be better suited to the job, but I'm unsure offhand whether it would reliably prevent concurrent installation of the obsoleted RPM.

There might be other, worse alternatives if none of that works out.


John

Jon Forrest

unread,
Apr 24, 2014, 11:22:10 PM4/24/14
to puppet...@googlegroups.com
A very clever co-worker managed to come with a solution.

Changing

package {
'mysql':
provider => "yum",
ensure => purged,
}

to

package {
'mysql.x86-64':
provider => "yum",
ensure => purged,
}

solved the problem.

I'm not sure why this works. I suspect it's because adding the ".x86-64"
somehow prevents the pattern from matching Percona. I'm going to
check this.

This approach is easier than creating a custom fact.

Thanks for all the suggestions.

Jon Forrest

Walter Heck

unread,
Apr 25, 2014, 8:31:07 AM4/25/14
to puppet...@googlegroups.com
Why don't you use the puppetlabs-mysql module? There you can use percona simply by modifying a few parameters, circumventing this whole issue.

just my 2 cents :)

cheers,

Walter

Jon Forrest

unread,
Apr 26, 2014, 12:31:18 AM4/26/14
to puppet...@googlegroups.com
You're right - I could have. Maybe I should have. But,
I like little puzzles like this because they help me
learn more about Puppet.

Jon Forrest


Jochen Haeberle

unread,
Dec 9, 2014, 7:50:36 AM12/9/14
to puppet...@googlegroups.com, jlfo...@berkeley.edu
Hi,

well at least on my debian, the percona-server package "provides" mysql, a meta-package. Installing Percona sees to it that MySQL (or MariaDB) is purged from the system first. So the way I see it, you have no need to remove mysql from your machine. Just install percona-server, this will see to the removel of mysql.

Regards
Jochen
Reply all
Reply to author
Forward
0 new messages