Search code examples
puppet

Puppet noop When Executable does not exist yet


The following is a simplified manifest I am running:

package {'ruby2.4':
  ensure => installed
}

exec { "gem2.4_install_bundler":
  command => "/usr/bin/gem2.4 install bundler",
  require => Package['ruby2.4']
}

Puppet apply runs this manifest correctly i.e

  1. installs ruby2.4 package (which includes gem2.4)

  2. Installs bundler using gem2.4

However, puppet apply --noop FAILS because puppet cannot find the executable '/usr/bin/gem2.4' because ruby2.4 is not installed with --noop.

My question is if there is a standard way to test a scenario like this with puppet apply --noop? To validate that my puppet manifest is executing correctly?

It occurs to me that I may have to parse the output and validate the order of the executions. If this is the case, is there a standard way/tool for this?

A last resort is a very basic check that the puppet at least runs, which can be determined with the --detailed-exitcodes option. (a code different to 1).

Thank you in advance


Solution

  • rspec-puppet is the standard tool for that level of verification. It can build a catalog from the manifest (e.g. for a class, defined type, or host) and then you can write tests to verify the contents.

    In your case you could verify that the package resource exists, that the exec resource exists, and verify the ordering between them. This would be just as effective as running the agent with --noop mode and parsing the output - but easier and cheaper to run.

    rspec-puppet works best with modules, so assuming you follow the setup for your module from the website (adding rspec-puppet to your Gemfile, running rspec-puppet-init), and let's say this is in a class called ruby24, a simple spec in spec/classes/ruby24_spec.rb would be:

    require 'spec_helper'
    
    describe 'ruby24' do
      it { is_expected.to compile.with_all_deps }
      it { is_expected.to contain_package('ruby2.4').with_ensure('installed') }
      it { is_expected.to contain_exec('gem2.4_install_bundler').with_command('/usr/bin/gem2.4 install bundler') }
      it { is_expected.to contain_exec('gem2.4_install_bundler').that_requires('Package[ruby2.4]') }
    end