Skip to content

Commit 88f21c2

Browse files
committed
not_if and only_if are now global - you can apply them to any resource.
1 parent 689dd2f commit 88f21c2

6 files changed

Lines changed: 173 additions & 53 deletions

File tree

chef/lib/chef/mixin/command.rb

Lines changed: 58 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,64 @@ class Chef
2525
module Mixin
2626
module Command
2727

28+
# If command is a block, returns true if the block returns true, false if it returns false.
29+
# ("Only run this resource if the block is true")
30+
#
31+
# If the command is not a block, executes the command. If it returns any status other than
32+
# 0, it returns false (clearly, a 0 status code is true)
33+
#
34+
# === Parameters
35+
# command<Block>, <String>:: A block to check, or a string to execute
36+
#
37+
# === Returns
38+
# true:: Returns true if the block is true, or if the command returns 0
39+
# false:: Returns false if the block is false, or if the command returns a non-zero exit code.
40+
def only_if(command)
41+
if Proc === command
42+
res = command.call
43+
unless res
44+
return false
45+
end
46+
else
47+
status = popen4(command) { |p, i, o, e| i.close }
48+
if status.exitstatus != 0
49+
return false
50+
end
51+
end
52+
true
53+
end
54+
55+
module_function :only_if
56+
57+
# If command is a block, returns false if the block returns true, true if it returns false.
58+
# ("Do not run this resource if the block is true")
59+
#
60+
# If the command is not a block, executes the command. If it returns a 0 exitstatus, returns false.
61+
# ("Do not run this resource if the command returns 0")
62+
#
63+
# === Parameters
64+
# command<Block>, <String>:: A block to check, or a string to execute
65+
#
66+
# === Returns
67+
# true:: Returns true if the block is false, or if the command returns a non-zero exit status.
68+
# false:: Returns false if the block is true, or if the command returns a 0 exit status.
69+
def not_if(command)
70+
if Proc === command
71+
res = command.call
72+
if res
73+
return false
74+
end
75+
else
76+
status = popen4(command) { |p, i, o, e| i.close }
77+
if status.exitstatus == 0
78+
return false
79+
end
80+
end
81+
true
82+
end
83+
84+
module_function :not_if
85+
2886
def run_command(args={})
2987
if args.has_key?(:creates)
3088
if File.exists?(args[:creates])
@@ -33,39 +91,6 @@ def run_command(args={})
3391
end
3492
end
3593

36-
if args.has_key?(:only_if)
37-
if Proc === args[:only_if]
38-
res = args[:only_if].call
39-
unless res
40-
Chef::Log.debug("Skipping #{args[:command_string]} - only_if #{args[:only_if]}")
41-
return false
42-
end
43-
else
44-
status = popen4(args[:only_if]) { |p, i, o, e| }
45-
if status.exitstatus != 0
46-
Chef::Log.debug("Skipping #{args[:command_string]} - only_if #{args[:only_if]} returned #{status.exitstatus}")
47-
return false
48-
end
49-
end
50-
end
51-
52-
if args.has_key?(:not_if)
53-
if Proc === args[:not_if]
54-
res = args[:not_if].call
55-
unless res
56-
Chef::Log.debug("Skipping #{args[:command_string]} - not_if #{args[:not_if]}")
57-
return false
58-
end
59-
else
60-
Chef::Log.debug("I should be running '#{args[:not_if]}'")
61-
status = popen4(args[:not_if]) { |p, i, o, e| }
62-
if status.exitstatus == 0
63-
Chef::Log.debug("Skipping #{args[:command_string]} - not_if #{args[:not_if]} returned #{status.exitstatus}")
64-
return false
65-
end
66-
end
67-
end
68-
6994
exec_processing_block = lambda do |pid, stdin, stdout, stderr|
7095
stdin.close
7196

chef/lib/chef/resource.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ def initialize(name, collection=nil, node=nil)
4646
@updated = false
4747
@supports = {}
4848
@ignore_failure = false
49+
@not_if = nil
50+
@only_if = nil
4951
sline = caller(4).shift
5052
if sline
5153
@source_line = sline.gsub!(/^(.+):(.+):.+$/, '\1 line \2')
@@ -182,6 +184,24 @@ def self.json_create(o)
182184
resource
183185
end
184186

187+
def only_if(arg=nil, &blk)
188+
if Kernel.block_given?
189+
@only_if = blk
190+
else
191+
@only_if = arg if arg
192+
end
193+
@only_if
194+
end
195+
196+
def not_if(arg=nil, &blk)
197+
if Kernel.block_given?
198+
@not_if = blk
199+
else
200+
@not_if = arg if arg
201+
end
202+
@not_if
203+
end
204+
185205
private
186206

187207
def check_timing(timing)

chef/lib/chef/resource/execute.rb

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,10 @@ def initialize(name, collection=nil, node=nil)
3030
@cwd = nil
3131
@environment = nil
3232
@group = nil
33-
@only_if = nil
3433
@path = nil
3534
@notify_only = false
3635
@returns = 0
3736
@timeout = nil
38-
@not_if = nil
3937
@user = nil
4038
@allowed_actions.push(:run)
4139
end
@@ -79,15 +77,6 @@ def group(arg=nil)
7977
:kind_of => [ String, Integer ]
8078
)
8179
end
82-
83-
def only_if(arg=nil, &blk)
84-
if Kernel.block_given?
85-
@only_if = blk
86-
else
87-
@only_if = arg if arg
88-
end
89-
@only_if
90-
end
9180

9281
def path(arg=nil)
9382
set_or_return(
@@ -112,15 +101,6 @@ def timeout(arg=nil)
112101
:kind_of => [ Integer ]
113102
)
114103
end
115-
116-
def not_if(arg=nil, &blk)
117-
if Kernel.block_given?
118-
@not_if = blk
119-
else
120-
@not_if = arg if arg
121-
end
122-
@not_if
123-
end
124104

125105
def user(arg=nil)
126106
set_or_return(

chef/lib/chef/runner.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,24 @@ def converge
6060
@collection.each do |resource|
6161
begin
6262
Chef::Log.debug("Processing #{resource}")
63+
64+
# Check if this resource has an only_if block - if it does, skip it.
65+
if resource.only_if
66+
unless Chef::Mixin::Command.only_if(resource.only_if)
67+
Chef::Log.debug("Skipping #{resource} due to only_if")
68+
next
69+
end
70+
end
71+
72+
# Check if this resource has a not_if block - if it does, skip it.
73+
if resource.not_if
74+
unless Chef::Mixin::Command.not_if(resource.not_if)
75+
Chef::Log.debug("Skipping #{resource} due to not_if")
76+
next
77+
end
78+
end
79+
80+
# Walk the actions for this resource, building the provider and running each.
6381
action_list = resource.action.kind_of?(Array) ? resource.action : [ resource.action ]
6482
action_list.each do |ra|
6583
provider = build_provider(resource)

chef/spec/unit/runner_spec.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,28 @@
6565
@runner.converge
6666
end
6767

68+
it "should check a resources only_if, if it is provided" do
69+
@collection[0].should_receive(:only_if).and_return(nil)
70+
@runner.converge
71+
end
72+
73+
it "should send a resources only_if to Chef::Mixin::Command.only_if" do
74+
@collection[0].should_receive(:only_if).twice.and_return(true)
75+
Chef::Mixin::Command.should_receive(:only_if).with(true).and_return(false)
76+
@runner.converge
77+
end
78+
79+
it "should send a resources not_if to Chef::Mixin::Command.not_if" do
80+
@collection[0].should_receive(:not_if).twice.and_return(true)
81+
Chef::Mixin::Command.should_receive(:not_if).with(true).and_return(false)
82+
@runner.converge
83+
end
84+
85+
it "should check a resources not_if, if it is provided" do
86+
@collection[0].should_receive(:not_if).and_return(nil)
87+
@runner.converge
88+
end
89+
6890
it "should raise exceptions as thrown by a provider" do
6991
Chef::Platform.stub!(:find_provider_for_node).once.and_return(Chef::Provider::SnakeOil)
7092
provider = Chef::Provider::SnakeOil.new(@node, @collection[0])
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#
2+
# Cookbook Name:: global-onlyif
3+
# Recipe:: default
4+
#
5+
# Copyright 2008, Example Com
6+
#
7+
# Licensed under the Apache License, Version 2.0 (the "License");
8+
# you may not use this file except in compliance with the License.
9+
# You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS,
15+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
18+
#
19+
20+
file "/tmp/neverhappen" do
21+
only_if do false; end
22+
end
23+
24+
file "/tmp/stillnothappening" do
25+
not_if do true; end
26+
end
27+
28+
file "/tmp/seriouslynothappening" do
29+
only_if "false"
30+
end
31+
32+
file "/tmp/yepstillnot" do
33+
not_if "true"
34+
end
35+
36+
file "/tmp/shouldhappen" do
37+
only_if do true; end
38+
action [:create, :delete]
39+
end
40+
41+
file "/tmp/shouldhappen" do
42+
only_if "true"
43+
action [:create, :delete]
44+
end
45+
46+
file "/tmp/shouldhappen" do
47+
not_if do false; end
48+
action [:create, :delete]
49+
end
50+
51+
file "/tmp/shouldhappen" do
52+
not_if "false"
53+
action [:create, :delete]
54+
end
55+

0 commit comments

Comments
 (0)