Search code examples
rubyduplicatespuppet

Puppet Install specific version of package depending on application version


I have a module which installs my Application. To install system packages i'm using virtual resource:

@package {[
    'unzip',
    'wget',
    'htop',
    'xorg-x11-server-Xvfb']:
      ensure => installed,
}

define myapp1_packages {
  realize(
    Package['unzip'],
    Package['fontconfig'],
    Package['libfreetype.so.6'])
}
@myapp1_packages{ 'myapp1_packages': }

Then I use realize in my manifest to install the above packages:

realize(myapp1_packages['myapp1_packages'])

But for each version of my application I also need appropriate versions of system packages.

I need something like that:

if $app_version == '1.0' {
    "install unzip-1xx"
    "install fontconfig-1-xx"
    "install libfreetype.so.6-1-x-xx"
elseif $app_version == '2.0'
    "install unzip-2xx"
    "install fontconfig-2-xx"
    "install libfreetype.so.6-2-x-xx"

What is most elegant way to do this? And is it possible to keep virtual resources in that case? I'm looking to use ensure_packages but i worried about resource duplication. Thanks for the help!


Solution

  • The best thing to do here is to make $app_version a parameter for your module: https://docs.puppet.com/puppet/4.10/lang_classes.html#class-parameters-and-variables. Note an example from the documentation here: https://docs.puppet.com/puppet/4.10/lang_classes.html#appendix-smart-parameter-defaults.

    For your situation, the class would look like:

    myclass($app_version = 'default version') {
      if $app_version == '1.0' {
        @package { 'unzip': ensure => '1xx' }
        @package { 'fontconfig': ensure => '1-xx' }
        @package { 'libfreetype': ensure => '6-1-xx' }
      }
      elsif $app_version == '2.0' {
        @package { 'unzip': ensure => '2xx' }
        @package { 'fontconfig': ensure => '2-xx' }
        @package { 'libfreetype': ensure => '6-2-xx' }
      }
    }
    

    thus also allowing you to retain your virtual resources.

    You can then pass parameters to this class by declaring it like:

    class { 'myclass': app_version => '2.0' }
    

    or using automatic data bindings with hieradata:

    # puppet manifest
    include myclass
    
    # hieradata
    myclass::app_version: 2.0
    

    Your collector elsewhere will then realize the correct versions for your packages.