Search code examples
puppet

How to handle linux and windows in puppet modules?


I have a large Module written for linux systems. But I need it to work for windows so I want to rewrite it to handle both.

There are a lot of manifests and from what I can see so far, most of it should be ok with Windows as puppet would see it's running on windows and select the best provider.

However there are some parts that won't work. As an example this exec will not work on windows

    exec { 'touch_file' :
      command => 'touch /etc/test.txt',
      path    => ['/bin', '/usr/bin'],
      cwd     => '/tmp',
      creates => '/etc/test.txt',
    }

This would work in linux but in Windows I would change this to a powershell command and also change creates, cwd and path. I could change each part to a ${variable} and have a case statement above the Exec statement that picks the right variables based on ::osgroup but I'm not sure if this is the best way to handle this. Is there a better way of handling multi OS modules?


Solution

  • Sometimes it's better to have different execs based on the OS you are targeting. See https://github.com/puppetlabs/puppetlabs-puppet_agent as a good example of this:

    https://github.com/puppetlabs/puppetlabs-puppet_agent/blob/f76482b2b68bd80115de87037ba71068bea4e35b/manifests/init.pp#L36-L46

        if $::osfamily == 'windows' {
          class { '::puppet_agent::prepare': } ->
          class { '::puppet_agent::windows::install': }
        }
        else {
    
          if $::operatingsystem == 'SLES' and $::operatingsystemmajrelease == '10' {
            $_package_file_name = "${puppet_agent::package_name}-${puppet_agent::params::master_agent_version}-1.sles10.${::architecture}.rpm"
          } elsif $::operatingsystem == 'Solaris' and $::operatingsystemmajrelease == '10' {
            $_package_file_name = "${puppet_agent::package_name}-${puppet_agent::params::master_agent_version}-1.i386.pkg.gz"
          }
    
          class { '::puppet_agent::prepare':
            package_file_name => $_package_file_name,
          } ->
          class { '::puppet_agent::install':
            package_file_name => $_package_file_name,
          } ->
          class { '::puppet_agent::service': }
    
          contain '::puppet_agent::prepare'
          contain '::puppet_agent::install'
          contain '::puppet_agent::service'
        }