summaryrefslogtreecommitdiff
path: root/lib/chef/role.rb
diff options
context:
space:
mode:
authorBen Somers <somers.ben@gmail.com>2013-05-14 11:25:07 -0700
committerBen Somers <somers.ben@gmail.com>2014-06-08 16:33:58 -0700
commitfb8375f99b6cf192484049383a9349416873e1fa (patch)
tree7fd203472a4858e138c26b57807053bb42f26184 /lib/chef/role.rb
parent92519eb2cf7ae1b362f22d5710a229c5809a47cc (diff)
downloadchef-fb8375f99b6cf192484049383a9349416873e1fa.tar.gz
Enabling storage of roles in subdirectories
Storing roles in subdirectories is already effectively enabled for Hosted Chef, as the directory structure gets flattened when they are uploaded. But it is not currently possible with Chef-Solo; one has to flatten the directory manually before running Chef-Solo. This patch changes that behavior, and enables Chef-Solo with roles in subdirectories.
Diffstat (limited to 'lib/chef/role.rb')
-rw-r--r--lib/chef/role.rb20
1 files changed, 11 insertions, 9 deletions
diff --git a/lib/chef/role.rb b/lib/chef/role.rb
index 6ad58b816d..6f2c6318fc 100644
--- a/lib/chef/role.rb
+++ b/lib/chef/role.rb
@@ -231,22 +231,24 @@ class Chef
end
# Load a role from disk - prefers to load the JSON, but will happily load
- # the raw rb files as well.
+ # the raw rb files as well. Can search within directories in the role_path.
def self.from_disk(name, force=nil)
paths = Array(Chef::Config[:role_path])
+ paths.each do |path|
+ roles_files = Dir.glob(File.join(path, "**", "**"))
+ js_path = roles_files.detect { |file| file.match /#{name}\.json$/ }
+ rb_path = roles_files.detect { |file| file.match /#{name}\.rb$/ }
- paths.each do |p|
- js_file = File.join(p, "#{name}.json")
- rb_file = File.join(p, "#{name}.rb")
-
- if File.exists?(js_file) || force == "json"
+ if js_path && (File.exists?(js_path) || force == "json")
# from_json returns object.class => json_class in the JSON.
- return Chef::JSONCompat.from_json(IO.read(js_file))
- elsif File.exists?(rb_file) || force == "ruby"
+ return Chef::JSONCompat.from_json(IO.read(js_path))
+ elsif rb_path && (File.exists?(rb_path) || force == "ruby")
role = Chef::Role.new
role.name(name)
- role.from_file(rb_file)
+ role.from_file(rb_path)
return role
+ else
+ raise Chef::Exceptions::RoleNotFound, "Role '#{name}' could not be loaded from disk"
end
end