Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions lib/puppet/type/exec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ module Puppet
command only when some other resource is changed. (See the notes on refreshing
below.)

The `enable_idempotency_check` attribute is used to check if one of the above mentioned
attributes has been set. The parameter defaults to `false` and raises an error if
enabled and no idempotency attributes has been set.

The state managed by an `exec` resource represents whether the specified command
_needs to be_ executed during the catalog run. The target state is always that
the command does not need to be executed. If the initial state is that the
Expand Down Expand Up @@ -582,6 +586,39 @@ def check(value)
end
end

newcheck(:enable_idempotency_check) do
desc <<-'EOT'
Warning: disabling idempotency validation might result in changes
in EVERY Puppet run!

Idempotency is ensured by setting either one of the following
attributes:

- `creates`
- `onlyif`
- `unless`
- `refreshonly`
EOT

defaultto :false
newvalues(:true, :false)

def check(value)
if value == :true
result = true
param = [:onlyif, :unless, :refreshonly, :creates]
result = false unless (resource.to_hash.keys & param).any?
unless result
raise ArgumentError, _("Missing idempotency. Set at least one of 'onlyif', 'unless', 'refreshonly', 'creates' or disable check by adding 'enable_idempotency_check => false' ")
end

result
else
true
end
end
end

# Exec names are not isomorphic with the objects.
@isomorphic = false

Expand Down
33 changes: 33 additions & 0 deletions spec/unit/type/exec_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,39 @@ def instance(path)
@test = Puppet::Type.type(:exec).new(:name => @executable)
end

describe "enable_idempotency_check" do

[:true, :false].each do |value|
it "should accept '#{value}'" do
@test[:enable_idempotency_check] = value
expect(@test[:enable_idempotency_check]).to eq(value)
end
end

[1, 0, "1", "0", "yes", "y", "no", "n"].each do |value|
it "should reject '#{value}'" do
expect { @test[:enable_idempotency_check] = value }.
to raise_error(Puppet::Error,
/Invalid value #{value.inspect}\. Valid values are true, false/
)
end
end

context "without an idempotency check" do
it "should raise error" do
type = Puppet::Type.type(:exec).new(:name => @command, :enable_idempotency_check => true)
expect(type[:enable_idempotency_check]).to eq(:true)
end
end

context "with an idempotency check" do
it "should not fail" do
type = Puppet::Type.type(:exec).new(:name => @command, :enable_idempotency_check => true, :refreshonly => true)
expect(type).to be
end
end
end

describe ":refreshonly" do
{ :true => false, :false => true }.each do |input, result|
it "should return '#{result}' when given '#{input}'" do
Expand Down