what is the right way to ensure specific version installed on puppet agent?

3,554 views
Skip to first unread message

shlo....@gmail.com

unread,
Dec 4, 2013, 2:19:55 AM12/4/13
to puppet...@googlegroups.com


Hi,

I wanted to install mysql-5.1.66 and make sure mysql-5.5.34 removed so I make a init.pp file and put in it:
class mysql {
    package { 'mysql':
        ensure => "5.1.66-2.el6_3",
        require => [Package['mysql-libs'],
                    Package['compat-mysql'],
                    Package['mysql-5.5.34']],
    }

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

    package { 'compat-mysql':
    provider => 'yum',
    ensure => 'absent',
    }

    package { 'mysql-5.5.34':
    provider => 'yum',
    ensure => 'absent',
    }
}

When I test it before, two weeks ago, it work okay. It remove mysql-5.5.34 and install mysql-5.1.66.
Today I saw the puppet agent don't have mysql install at all.
I tried to install it from the Unix command line  and got:
No package mysql-server-5.1.66-2.el6_3 available.
Error: Nothing to do


I believe that this version of mysql removed from the repository because it's old, but I don't want the old version to delete from my puppet agent.
I want my puppet agent to have mysql-5.1.66 even that it not exist in the repository.
Is it because the puppet did not find mysql in the repository so it delete it from my agent? or I'm doing something wrong?

Thanks.

 

jcbollinger

unread,
Dec 4, 2013, 9:56:34 AM12/4/13
to puppet...@googlegroups.com


On Wednesday, December 4, 2013 1:19:55 AM UTC-6, shlo....@gmail.com wrote:


Hi,

I wanted to install mysql-5.1.66 and make sure mysql-5.5.34 removed so I make a init.pp file and put in it:
class mysql {
    package { 'mysql':
        ensure => "5.1.66-2.el6_3",
        require => [Package['mysql-libs'],
                    Package['compat-mysql'],
                    Package['mysql-5.5.34']],
    }

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

    package { 'compat-mysql':
    provider => 'yum',
    ensure => 'absent',
    }

    package { 'mysql-5.5.34':
    provider => 'yum',
    ensure => 'absent',
    }


That last bit is useless, except inasmuch as there is a (definitely useless) reference to Package[''mysql-5.5.34''] earlier.  Puppet's RPM and YUM package providers will recognize <rpm name> and <rpm name>.<arch> as package names.  Ensuring Package['mysql-5.5.34'] absent is always a no-op because although Package['mysql'] might have version 5.5.34, that's doesn't make it a package named "mysql-5.5.34".

Moreover, this isn't an issue for the vast majority of RPM packages, because few RPMs accommodate multiple versions of the same package installed.  Unless you're dealing with custom-packaged RPMs specifically built to accommodate multiple versions -- and it doesn't look like you are -- your earlier version-specific declaration of package "mysql" should be sufficient to ensure that the only version of the "mysql" package is the one you specify (5.1.66-2.el6_3).

 
}

When I test it before, two weeks ago, it work okay. It remove mysql-5.5.34 and install mysql-5.1.66.
Today I saw the puppet agent don't have mysql install at all.
I tried to install it from the Unix command line  and got:
No package mysql-server-5.1.66-2.el6_3 available.
Error: Nothing to do


I believe that this version of mysql removed from the repository because it's old, but I don't want the old version to delete from my puppet agent.
I want my puppet agent to have mysql-5.1.66 even that it not exist in the repository.
Is it because the puppet did not find mysql in the repository so it delete it from my agent?


No.

 
or I'm doing something wrong?



Yes.

Your package declarations have a hidden inconsistency that Puppet is unable to diagnose.  You specify that package "mysql-libs" must be purged, but that's not actually what you want, because packages mysql and mysql-server depend on mysql-libs.  By ensuring mysql-libs purged, you force it and all packages that depend on it to be removed (if mysql-libs is present) every time the agent runs.  That's why mysql-5.1.66 and mysql-server-5.1.66 got removed.  It is surely not what you actually want, even if the mysql-5.1.66 packages were still available in your configured repositories.  (And this is yet another reason why the declaration of package "mysql-5.5.34" is useless.)

You have committed one of the classic Puppet blunders: writing manifests that focus on state transitions instead of on the desired target state.  I say that because the only reason I can imaging for declaring mysql-libs purged is to facilitate downgrading mysql to version 5.1.66 from a later version.

There are several things you should do:
  1. Create and maintain a local package repository for at least those packages you depend upon, plus their dependencies.  Myself, I maintain a complete local mirror of all the essential repositories I depend on.  There are multiple advantages, but the most relevant one here is that you can avoid packages being yanked out from under you.
  2. Remove the inconsistency in your declarations.
There are several approaches to (2), but I'd recommend creating a custom fact to report the installed version of mysql-libs, and making its purge conditional on that value.  The Puppet side might look like this:

class mysql {
  $target_version = '5.1.66'
  $target_release = '2.el6_3'

  package { 'mysql': ensure => "${target_version}-${target_release)" }

  # assumes that mysql-libs version must match mysql version;
  # $::mysql_libs_version is a custom fact you must provide:
  if $::mysql_libs_version != '' and versioncmp($target_version, $::mysql_libs_version) < 0 {
    package { 'mysql-libs':
      ensure => 'purged'
      before => Package['mysql']
    }
  }

  package { 'compat-mysql': ensure => 'absent' }
}

Note that there is no need for a resource relationship between Package['compat-mysql'] and Package['mysql'], because it doesn't matter in which relative order these resources are applied.  Note also that there is no longer any declaration of a package "mysql-5.5.34"; it is unneeded.

Additionally, note that it is not normally necessary to explicitly specify a provider in your resource declarations.

See http://docs.puppetlabs.com/guides/custom_facts.html for information about writing and distributing custom facts.


John

shlo....@gmail.com

unread,
Dec 5, 2013, 2:31:02 AM12/5/13
to puppet...@googlegroups.com

Thank you very much for your detailed answer.

Winn Johnston

unread,
Jul 26, 2016, 4:06:50 AM7/26/16
to Puppet Users
Syntax error 

  package { 'mysql': ensure => "${target_version}-${target_release)" }

  package { 'mysql': ensure => "${target_version}-${target_release}" }

-winn
Reply all
Reply to author
Forward
0 new messages