diff options
author | Steven Murawski <steven.murawski@gmail.com> | 2017-04-05 12:20:27 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-04-05 12:20:27 -0500 |
commit | d76a39dca708b712ce6566d24275414b08789d37 (patch) | |
tree | d8fa7fee2abc01d9da8241ff34fd64655de07f71 | |
parent | a9d0cfb3bcb995d60e096a755e4e58fa47f40047 (diff) | |
parent | 1c2355a9dfde6221642095da911f8c9679c46975 (diff) | |
download | chef-d76a39dca708b712ce6566d24275414b08789d37.tar.gz |
Merge pull request #6015 from coderanger/root-alias
Implement RFC033: Root aliases
-rw-r--r-- | RELEASE_NOTES.md | 6 | ||||
-rw-r--r-- | lib/chef/cookbook_version.rb | 17 | ||||
-rw-r--r-- | lib/chef/run_context/cookbook_compiler.rb | 17 | ||||
-rw-r--r-- | spec/data/cookbooks/aliased/attributes.rb | 1 | ||||
-rw-r--r-- | spec/data/cookbooks/aliased/metadata.rb | 2 | ||||
-rw-r--r-- | spec/data/cookbooks/aliased/recipe.rb | 3 | ||||
-rw-r--r-- | spec/functional/root_alias_spec.rb | 58 | ||||
-rw-r--r-- | spec/unit/cookbook_loader_spec.rb | 8 |
8 files changed, 99 insertions, 13 deletions
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 03be083bdb..0a34e3c17a 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -257,3 +257,9 @@ The behavior of the `clear_sources` property is now to only add `--clear-sources ### `knife cookbook site vendor` has been removed Please use `knife cookbook site install` instead. + +### Cookbook root aliases + +Rather than `attributes/default.rb`, cookbooks can now use `attributes.rb` in +the root of the cookbook. Similarly for a single default recipe, cookbooks can +use `recipe.rb` in the root of the cookbook. diff --git a/lib/chef/cookbook_version.rb b/lib/chef/cookbook_version.rb index 738f98929e..dcb8c97548 100644 --- a/lib/chef/cookbook_version.rb +++ b/lib/chef/cookbook_version.rb @@ -134,11 +134,24 @@ class Chef end def attribute_filenames_by_short_filename - @attribute_filenames_by_short_filename ||= filenames_by_name(files_for("attributes")) + @attribute_filenames_by_short_filename ||= begin + name_map = filenames_by_name(files_for("attributes")) + root_alias = cookbook_manifest.root_files.find { |record| record[:name] == "attributes.rb" } + name_map["default"] = root_alias[:full_path] if root_alias + name_map + end end def recipe_filenames_by_name - @recipe_filenames_by_name ||= filenames_by_name(files_for("recipes")) + @recipe_filenames_by_name ||= begin + name_map = filenames_by_name(files_for("recipes")) + root_alias = cookbook_manifest.root_files.find { |record| record[:name] == "recipe.rb" } + if root_alias + Chef::Log.error("Cookbook #{name} contains both recipe.rb and and recipes/default.rb, ignoring recipes/default.rb") if name_map["default"] + name_map["default"] = root_alias[:full_path] + end + name_map + end end def metadata=(metadata) diff --git a/lib/chef/run_context/cookbook_compiler.rb b/lib/chef/run_context/cookbook_compiler.rb index 94635be03d..ea5931ac75 100644 --- a/lib/chef/run_context/cookbook_compiler.rb +++ b/lib/chef/run_context/cookbook_compiler.rb @@ -105,7 +105,7 @@ class Chef # according to #cookbook_order; within a cookbook, +default.rb+ is loaded # first, then the remaining attributes files in lexical sort order. def compile_attributes - @events.attribute_load_start(count_files_by_segment(:attributes)) + @events.attribute_load_start(count_files_by_segment(:attributes, "attributes.rb")) cookbook_order.each do |cookbook| load_attributes_from_cookbook(cookbook) end @@ -166,7 +166,16 @@ class Chef def load_attributes_from_cookbook(cookbook_name) list_of_attr_files = files_in_cookbook_by_segment(cookbook_name, :attributes).dup - if default_file = list_of_attr_files.find { |path| File.basename(path) == "default.rb" } + root_alias = cookbook_collection[cookbook_name].files_for(:root_files).find { |record| record[:name] == "attributes.rb" } + default_file = list_of_attr_files.find { |path| File.basename(path) == "default.rb" } + if root_alias + if default_file + Chef::Log.error("Cookbook #{cookbook_name} contains both attributes.rb and and attributes/default.rb, ignoring attributes/default.rb") + list_of_attr_files.delete(default_file) + end + # The actual root_alias path decoding is handled in CookbookVersion#attribute_filenames_by_short_filename + load_attribute_file(cookbook_name.to_s, "default") + elsif default_file list_of_attr_files.delete(default_file) load_attribute_file(cookbook_name.to_s, default_file) end @@ -259,9 +268,9 @@ class Chef ordered_cookbooks << cookbook end - def count_files_by_segment(segment) + def count_files_by_segment(segment, root_alias = nil) cookbook_collection.inject(0) do |count, cookbook_by_name| - count + cookbook_by_name[1].segment_filenames(segment).size + count + cookbook_by_name[1].segment_filenames(segment).size + (root_alias ? cookbook_by_name[1].files_for(:root_files).select { |record| record[:name] == root_alias }.size : 0) end end diff --git a/spec/data/cookbooks/aliased/attributes.rb b/spec/data/cookbooks/aliased/attributes.rb new file mode 100644 index 0000000000..3a3bab96e1 --- /dev/null +++ b/spec/data/cookbooks/aliased/attributes.rb @@ -0,0 +1 @@ +default["aliased"]["attr"] = "value" diff --git a/spec/data/cookbooks/aliased/metadata.rb b/spec/data/cookbooks/aliased/metadata.rb new file mode 100644 index 0000000000..e3b2b96177 --- /dev/null +++ b/spec/data/cookbooks/aliased/metadata.rb @@ -0,0 +1,2 @@ +name "aliased" +version "1.0.0" diff --git a/spec/data/cookbooks/aliased/recipe.rb b/spec/data/cookbooks/aliased/recipe.rb new file mode 100644 index 0000000000..d82e58fbcd --- /dev/null +++ b/spec/data/cookbooks/aliased/recipe.rb @@ -0,0 +1,3 @@ +ruby_block "root alias" do + block { } +end diff --git a/spec/functional/root_alias_spec.rb b/spec/functional/root_alias_spec.rb new file mode 100644 index 0000000000..e26f41ff67 --- /dev/null +++ b/spec/functional/root_alias_spec.rb @@ -0,0 +1,58 @@ +# +# Copyright:: Copyright 2017, Noah Kantrowitz +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "spec_helper" + +describe "root aliases" do + let(:chef_repo_path) { File.expand_path(File.join(CHEF_SPEC_DATA, "cookbooks")) } + let(:cookbook_collection) do + cl = Chef::CookbookLoader.new(chef_repo_path) + cl.load_cookbooks + Chef::CookbookCollection.new(cl) + end + let(:node) do + node = Chef::Node.new + node.run_list << "aliased" + node.automatic[:recipes] = [] + node + end + let(:events) { Chef::EventDispatch::Dispatcher.new } + let(:run_context) { Chef::RunContext.new(node, cookbook_collection, events) } + before do + node.run_context = run_context + end + + describe "attributes root aliases" do + it "should load attributes.rb when included directly" do + node.include_attribute("aliased") + expect(node["aliased"]["attr"]).to eq "value" + end + + it "should load attributes.rb when loading a cookbook" do + run_context.load(node.run_list.expand("_default")) + expect(node["aliased"]["attr"]).to eq "value" + end + end + + describe "recipe root aliased" do + it "should load recipe.rb" do + run_context.load(node.run_list.expand("_default")) + run_context.include_recipe("aliased") + expect(run_context.resource_collection.map(&:to_s)).to eq ["ruby_block[root alias]"] + end + end +end diff --git a/spec/unit/cookbook_loader_spec.rb b/spec/unit/cookbook_loader_spec.rb index dd731b53d3..a7602da3b4 100644 --- a/spec/unit/cookbook_loader_spec.rb +++ b/spec/unit/cookbook_loader_spec.rb @@ -99,13 +99,7 @@ describe Chef::CookbookLoader do cookbook_loader.each do |cookbook_name, cookbook| seen << cookbook_name end - expect(seen[0]).to eq("angrybash") - expect(seen[1]).to eq("apache2") - expect(seen[2]).to eq("borken") - expect(seen[3]).to eq("ignorken") - expect(seen[4]).to eq("java") - expect(seen[5]).to eq("name-mismatch") - expect(seen[6]).to eq("openldap") + expect(seen).to eq %w{aliased angrybash apache2 borken ignorken java name-mismatch openldap preseed supports-platform-constraints} end end |