Skip to content

Commit e30dc05

Browse files
committed
run list expansion with env for env-agnostic run lists; tests
* add tests for multiply nested roles with env specific run lists * fix env-aware run list expansion to not depend on run lists being aware of their environment affiliation.
1 parent 507c328 commit e30dc05

6 files changed

Lines changed: 71 additions & 17 deletions

File tree

chef/lib/chef/node.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -419,15 +419,15 @@ def reset_defaults_and_overrides
419419
# on the command line)
420420
#
421421
# Returns the fully-expanded list of recipes.
422-
#
422+
#--
423423
# TODO: timh/cw, 5-14-2010: Should this method exist? Should we
424424
# instead modify default_attrs and override_attrs whenever our
425425
# run_list is mutated? Or perhaps do something smarter like
426426
# on-demand generation of default_attrs and override_attrs,
427427
# invalidated only when run_list is mutated?
428428
def expand!
429-
# This call should only be called on a chef-client run.
430-
expansion = run_list.expand('server')
429+
# This call should only be called on a chef-client run if you're going to save it later
430+
expansion = run_list.expand('server', :environment => chef_environment)
431431
raise Chef::Exceptions::MissingRole if expansion.errors?
432432

433433
self[:tags] = Array.new unless attribute?(:tags)

chef/lib/chef/role.rb

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ def run_list(*args)
115115
alias_method :recipes, :run_list
116116

117117
# For run_list expansion
118-
def run_list_for_environment(environment='_default')
119-
if env_run_lists[environment].nil? || env_run_lists[environment].empty?
118+
def run_list_for(environment='_default')
119+
if env_run_lists[environment].nil?
120120
run_list
121121
else
122122
env_run_lists[environment]
@@ -127,18 +127,13 @@ def run_list_for_environment(environment='_default')
127127
def env_run_lists(env_run_lists=nil)
128128
if (!env_run_lists.nil? && !env_run_lists.empty?)
129129
@env_run_lists.clear
130-
env_run_lists.each do |k,v|
131-
@env_run_lists[k] = Chef::RunList.new(*Array(v)) unless v.nil?
132-
end
130+
env_run_lists.each { |k,v| @env_run_lists[k] = Chef::RunList.new(*Array(v))}
133131
@env_run_lists["_default"] = run_list
134132
end
135133
@env_run_lists
136134
end
137135

138-
# def recipes(*args)
139-
# Chef::Log.warn "Chef::Role#recipes method is deprecated. Please use Chef::Role#run_list"
140-
# run_list(*args)
141-
# end
136+
alias :env_run_list :env_run_lists
142137

143138
def default_attributes(arg=nil)
144139
set_or_return(

chef/lib/chef/run_list.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,11 @@ def remove(item)
130130
alias :delete :remove
131131

132132

133-
def expand(data_source='server', couchdb=nil, rest=nil)
133+
def expand(data_source='server', expansion_opts={})
134134
couchdb = couchdb ? couchdb : Chef::CouchDB.new
135135

136-
expansion = expansion_for_data_source(data_source, :couchdb => couchdb, :rest => rest)
137-
expansion.expand(@chef_environment)
136+
expansion = expansion_for_data_source(data_source, expansion_opts)
137+
expansion.expand(expansion_opts[:environment])
138138
expansion
139139
end
140140

chef/lib/chef/run_list/run_list_expansion.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def expand(environment='_default')
7575
when :role
7676
if role = inflate_role(entry.name)
7777
apply_role_attributes(role)
78-
@run_list_items.insert(index + 1, *role.run_list_for_environment(environment).run_list_items)
78+
@run_list_items.insert(index + 1, *role.run_list_for(environment).run_list_items)
7979
end
8080
end
8181
end

chef/spec/unit/role_spec.rb

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,12 +202,30 @@
202202
before do
203203
@role.name("base")
204204
@role.run_list << "recipe[nagios::client]" << "recipe[tims-acl::bork]"
205+
@role.env_run_list["prod"] = Chef::RunList.new(*(@role.run_list.to_a << "recipe[prod-base]"))
206+
@role.env_run_list["dev"] = Chef::RunList.new
205207
end
206208

207-
it "returns the default run list when no environment is selected" do
209+
it "uses the default run list as *the* run_list" do
208210
@role.run_list.should == Chef::RunList.new("recipe[nagios::client]", "recipe[tims-acl::bork]")
209211
end
210212

213+
it "gives the default run list as the when getting the _default run list" do
214+
@role.run_list_for("_default").should == @role.run_list
215+
end
216+
217+
it "gives an environment specific run list" do
218+
@role.run_list_for("prod").should == Chef::RunList.new("recipe[nagios::client]", "recipe[tims-acl::bork]", "recipe[prod-base]")
219+
end
220+
221+
it "gives the default run list when no run list exists for the given environment" do
222+
@role.run_list_for("qa").should == @role.run_list
223+
end
224+
225+
it "gives the environment specific run list even if it is empty" do
226+
@role.run_list_for("dev").should == Chef::RunList.new
227+
end
228+
211229
end
212230

213231
end

chef/spec/unit/run_list_spec.rb

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,47 @@
188188
@rest.should_receive(:get_rest).with("roles/stubby")
189189
@run_list.expand
190190
end
191+
192+
describe "with an environment set" do
193+
before do
194+
@role.env_run_list["production"] = Chef::RunList.new( "one", "two", "five")
195+
end
196+
197+
it "expands the run list using the environment specific run list" do
198+
expansion = @run_list.expand("server", :environment => "production")
199+
expansion.recipes.should == %w{one two five kitty}
200+
end
201+
202+
describe "and multiply nested roles" do
203+
before do
204+
@multiple_rest_requests = mock("Chef::REST")
205+
206+
@role.env_run_list["production"] << "role[prod-base]"
207+
208+
@role_prod_base = Chef::Role.new
209+
@role_prod_base.name("prod-base")
210+
@role_prod_base.env_run_list["production"] = Chef::RunList.new("role[nested-deeper]")
211+
212+
213+
@role_nested_deeper = Chef::Role.new
214+
@role_nested_deeper.name("nested-deeper")
215+
@role_nested_deeper.env_run_list["production"] = Chef::RunList.new("recipe[prod-secret-sauce]")
216+
end
217+
218+
it "expands the run list using the specified environment for all nested roles" do
219+
Chef::REST.stub!(:new).and_return(@multiple_rest_requests)
220+
@multiple_rest_requests.should_receive(:get_rest).with("roles/stubby").and_return(@role)
221+
@multiple_rest_requests.should_receive(:get_rest).with("roles/prod-base").and_return(@role_prod_base)
222+
@multiple_rest_requests.should_receive(:get_rest).with("roles/nested-deeper").and_return(@role_nested_deeper)
223+
224+
expansion = @run_list.expand("server", :environment => "production")
225+
expansion.recipes.should == %w{one two five prod-secret-sauce kitty}
226+
end
227+
228+
end
229+
230+
end
231+
191232
end
192233

193234
describe "from couchdb" do

0 commit comments

Comments
 (0)