diff options
author | Thom May <thom@chef.io> | 2017-03-21 10:31:40 +0000 |
---|---|---|
committer | Thom May <thom@chef.io> | 2017-04-04 07:18:09 +0100 |
commit | 8f62f18a24e3213ef4b2f13a5abf0135bf6c2429 (patch) | |
tree | 7e3073c1b9a7aeb1fd54b08a191ad3bfcf0674f0 /lib/chef | |
parent | e3b9e67a880bcd658517f90a6add837c0e026798 (diff) | |
download | chef-8f62f18a24e3213ef4b2f13a5abf0135bf6c2429.tar.gz |
RFC 67: Remove cookbook segments
This implements RFC 67, which removes cookbook segments, and moves to a
single list of all the files contained in a cookbook. This allows us to
move forward with better audit modes and also proper shipping of ohai
plugins.
Signed-off-by: Thom May <thom@chef.io>
Diffstat (limited to 'lib/chef')
22 files changed, 340 insertions, 384 deletions
diff --git a/lib/chef/chef_fs/file_system/chef_server/chef_server_root_dir.rb b/lib/chef/chef_fs/file_system/chef_server/chef_server_root_dir.rb index 5030a0733f..63ce71ef40 100644 --- a/lib/chef/chef_fs/file_system/chef_server/chef_server_root_dir.rb +++ b/lib/chef/chef_fs/file_system/chef_server/chef_server_root_dir.rb @@ -103,11 +103,11 @@ class Chef end def get_json(path) - Chef::ServerAPI.new(chef_server_url, :client_name => chef_username, :signing_key_filename => chef_private_key, :api_version => "0").get(path) + chef_rest.get(path) end def chef_rest - Chef::ServerAPI.new(chef_server_url, :client_name => chef_username, :signing_key_filename => chef_private_key) + Chef::ServerAPI.new(chef_server_url, :client_name => chef_username, :signing_key_filename => chef_private_key, :api_version => "0") end def api_path diff --git a/lib/chef/chef_fs/file_system/chef_server/cookbook_artifacts_dir.rb b/lib/chef/chef_fs/file_system/chef_server/cookbook_artifacts_dir.rb index 0b82a64a0a..e4df7858a7 100644 --- a/lib/chef/chef_fs/file_system/chef_server/cookbook_artifacts_dir.rb +++ b/lib/chef/chef_fs/file_system/chef_server/cookbook_artifacts_dir.rb @@ -56,7 +56,7 @@ class Chef # to make this work. So instead, we make a temporary cookbook # symlinking back to real cookbook, and upload the proxy. def upload_cookbook(other, options) - cookbook_name, dash, identifier = other.name.rpartition("-") + cookbook_name, _, identifier = other.name.rpartition("-") Dir.mktmpdir do |temp_cookbooks_path| proxy_cookbook_path = "#{temp_cookbooks_path}/#{cookbook_name}" @@ -73,7 +73,7 @@ class Chef cookbook_to_upload.freeze_version if options[:freeze] # Instantiate a new uploader based on the proxy loader - uploader = Chef::CookbookUploader.new(cookbook_to_upload, force: options[:force], rest: root.chef_rest, policy_mode: true) + uploader = Chef::CookbookUploader.new(cookbook_to_upload, force: options[:force], rest: chef_rest, policy_mode: true) with_actual_cookbooks_dir(temp_cookbooks_path) do uploader.upload_cookbooks @@ -92,6 +92,10 @@ class Chef end end + def chef_rest + Chef::ServerAPI.new(root.chef_rest.url, root.chef_rest.options.merge(version_class: Chef::CookbookManifestVersions)) + end + def can_have_child?(name, is_dir) is_dir && name.include?("-") end diff --git a/lib/chef/chef_fs/file_system/chef_server/cookbook_dir.rb b/lib/chef/chef_fs/file_system/chef_server/cookbook_dir.rb index 8f5faf2183..64488ed705 100644 --- a/lib/chef/chef_fs/file_system/chef_server/cookbook_dir.rb +++ b/lib/chef/chef_fs/file_system/chef_server/cookbook_dir.rb @@ -49,18 +49,6 @@ class Chef attr_reader :cookbook_name, :version - COOKBOOK_SEGMENT_INFO = { - :attributes => { :ruby_only => true }, - :definitions => { :ruby_only => true }, - :recipes => { :ruby_only => true }, - :libraries => { :recursive => true }, - :templates => { :recursive => true }, - :files => { :recursive => true }, - :resources => { :ruby_only => true, :recursive => true }, - :providers => { :ruby_only => true, :recursive => true }, - :root_files => {}, - } - def add_child(child) @children << child end @@ -80,34 +68,29 @@ class Chef end def can_have_child?(name, is_dir) - # A cookbook's root may not have directories unless they are segment directories - return name != "root_files" && COOKBOOK_SEGMENT_INFO.keys.include?(name.to_sym) if is_dir + return name != "root_files" if is_dir true end def children if @children.nil? @children = [] - manifest = chef_object.manifest - COOKBOOK_SEGMENT_INFO.each do |segment, segment_info| - next unless manifest.has_key?(segment) - - # Go through each file in the manifest for the segment, and - # add cookbook subdirs and files for it. - manifest[segment].each do |segment_file| - parts = segment_file[:path].split("/") + manifest = chef_object.cookbook_manifest + manifest.by_parent_directory.each do |segment, files| + files.each do |file| + parts = file[:path].split("/") # Get or create the path to the file container = self parts[0, parts.length - 1].each do |part| old_container = container container = old_container.children.find { |child| part == child.name } if !container - container = CookbookSubdir.new(part, old_container, segment_info[:ruby_only], segment_info[:recursive]) + container = CookbookSubdir.new(part, old_container, false, true) old_container.add_child(container) end end # Create the file itself - container.add_child(CookbookFile.new(parts[parts.length - 1], container, segment_file)) + container.add_child(CookbookFile.new(parts[parts.length - 1], container, file)) end end @children = @children.sort_by { |c| c.name } @@ -165,7 +148,11 @@ class Chef end def rest - parent.rest + Chef::ServerAPI.new(parent.rest.url, parent.rest.options.merge(version_class: Chef::CookbookManifestVersions)) + end + + def chef_rest + Chef::ServerAPI.new(parent.chef_rest.url, parent.chef_rest.options.merge(version_class: Chef::CookbookManifestVersions)) end def chef_object @@ -187,7 +174,7 @@ class Chef old_retry_count = Chef::Config[:http_retry_count] begin Chef::Config[:http_retry_count] = 0 - @chef_object ||= Chef::CookbookVersion.from_hash(root.get_json(api_path)) + @chef_object ||= Chef::CookbookVersion.from_hash(chef_rest.get(api_path)) ensure Chef::Config[:http_retry_count] = old_retry_count end diff --git a/lib/chef/chef_fs/file_system/chef_server/cookbooks_dir.rb b/lib/chef/chef_fs/file_system/chef_server/cookbooks_dir.rb index 631562d7ef..4e8e68e364 100644 --- a/lib/chef/chef_fs/file_system/chef_server/cookbooks_dir.rb +++ b/lib/chef/chef_fs/file_system/chef_server/cookbooks_dir.rb @@ -74,13 +74,17 @@ class Chef def upload_cookbook(other, options) cookbook_to_upload = other.chef_object cookbook_to_upload.freeze_version if options[:freeze] - uploader = Chef::CookbookUploader.new(cookbook_to_upload, :force => options[:force], :rest => root.chef_rest) + uploader = Chef::CookbookUploader.new(cookbook_to_upload, :force => options[:force], :rest => chef_rest) with_actual_cookbooks_dir(other.parent.file_path) do uploader.upload_cookbooks end end + def chef_rest + Chef::ServerAPI.new(root.chef_rest.url, root.chef_rest.options.merge(version_class: Chef::CookbookManifestVersions)) + end + # Work around the fact that CookbookUploader doesn't understand chef_repo_path (yet) def with_actual_cookbooks_dir(actual_cookbook_path) old_cookbook_path = Chef::Config.cookbook_path diff --git a/lib/chef/chef_fs/file_system/chef_server/versioned_cookbooks_dir.rb b/lib/chef/chef_fs/file_system/chef_server/versioned_cookbooks_dir.rb index 172405763a..8da3718136 100644 --- a/lib/chef/chef_fs/file_system/chef_server/versioned_cookbooks_dir.rb +++ b/lib/chef/chef_fs/file_system/chef_server/versioned_cookbooks_dir.rb @@ -78,7 +78,7 @@ class Chef cookbook_to_upload.freeze_version if options[:freeze] # Instantiate a new uploader based on the proxy loader - uploader = Chef::CookbookUploader.new(cookbook_to_upload, :force => options[:force], :rest => root.chef_rest) + uploader = Chef::CookbookUploader.new(cookbook_to_upload, :force => options[:force], :rest => chef_rest) with_actual_cookbooks_dir(temp_cookbooks_path) do uploader.upload_cookbooks @@ -97,6 +97,10 @@ class Chef end end + def chef_rest + Chef::ServerAPI.new(root.chef_rest.url, root.chef_rest.options.merge(version_class: Chef::CookbookManifestVersions)) + end + def can_have_child?(name, is_dir) is_dir && name =~ Chef::ChefFS::FileSystem::ChefServer::VersionedCookbookDir::VALID_VERSIONED_COOKBOOK_NAME end diff --git a/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_cookbook_dir.rb b/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_cookbook_dir.rb index 31b538b9ce..b296901dd1 100644 --- a/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_cookbook_dir.rb +++ b/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_cookbook_dir.rb @@ -97,9 +97,9 @@ class Chef end def can_have_child?(name, is_dir) - if is_dir + if is_dir && !%w{ root_files .. . }.include?(name) # Only the given directories will be uploaded. - return Chef::ChefFS::FileSystem::ChefServer::CookbookDir::COOKBOOK_SEGMENT_INFO.keys.include?(name.to_sym) && name != "root_files" + return true elsif name == Chef::Cookbook::CookbookVersionLoader::UPLOADED_COOKBOOK_VERSION_FILE return false end @@ -128,8 +128,7 @@ class Chef protected def make_child_entry(child_name) - segment_info = Chef::ChefFS::FileSystem::ChefServer::CookbookDir::COOKBOOK_SEGMENT_INFO[child_name.to_sym] || {} - ChefRepositoryFileSystemCookbookEntry.new(child_name, self, nil, segment_info[:ruby_only], segment_info[:recursive]) + ChefRepositoryFileSystemCookbookEntry.new(child_name, self, nil, false, true) end def cookbook_version diff --git a/lib/chef/cookbook/cookbook_version_loader.rb b/lib/chef/cookbook/cookbook_version_loader.rb index b9de9a7482..35dac27fa5 100644 --- a/lib/chef/cookbook/cookbook_version_loader.rb +++ b/lib/chef/cookbook/cookbook_version_loader.rb @@ -9,15 +9,6 @@ class Chef class Cookbook class CookbookVersionLoader - FILETYPES_SUBJECT_TO_IGNORE = [ :attribute_filenames, - :definition_filenames, - :recipe_filenames, - :template_filenames, - :file_filenames, - :library_filenames, - :resource_filenames, - :provider_filenames] - UPLOADED_COOKBOOK_VERSION_FILE = ".uploaded-cookbook-version.json".freeze attr_reader :cookbook_settings @@ -44,16 +35,7 @@ class Chef @relative_path = /#{Regexp.escape(@cookbook_path)}\/(.+)$/ @metadata_loaded = false @cookbook_settings = { - :all_files => {}, - :attribute_filenames => {}, - :definition_filenames => {}, - :recipe_filenames => {}, - :template_filenames => {}, - :file_filenames => {}, - :library_filenames => {}, - :resource_filenames => {}, - :provider_filenames => {}, - :root_filenames => {}, + :all_files => {}, } @metadata_filenames = [] @@ -84,16 +66,6 @@ class Chef remove_ignored_files - load_as(:attribute_filenames, "attributes", "*.rb") - load_as(:definition_filenames, "definitions", "*.rb") - load_as(:recipe_filenames, "recipes", "*.rb") - load_recursively_as(:library_filenames, "libraries", "*") - load_recursively_as(:template_filenames, "templates", "*") - load_recursively_as(:file_filenames, "files", "*") - load_recursively_as(:resource_filenames, "resources", "*.rb") - load_recursively_as(:provider_filenames, "providers", "*.rb") - load_root_files - if empty? Chef::Log.warn "Found a directory #{cookbook_name} in the cookbook path, but it contains no cookbook files. skipping." end @@ -126,16 +98,6 @@ class Chef Chef::CookbookVersion.new(cookbook_name, *cookbook_paths).tap do |c| c.all_files = cookbook_settings[:all_files].values - c.attribute_filenames = cookbook_settings[:attribute_filenames].values - c.definition_filenames = cookbook_settings[:definition_filenames].values - c.recipe_filenames = cookbook_settings[:recipe_filenames].values - c.template_filenames = cookbook_settings[:template_filenames].values - c.file_filenames = cookbook_settings[:file_filenames].values - c.library_filenames = cookbook_settings[:library_filenames].values - c.resource_filenames = cookbook_settings[:resource_filenames].values - c.provider_filenames = cookbook_settings[:provider_filenames].values - c.root_filenames = cookbook_settings[:root_filenames].values - c.metadata_filenames = metadata_filenames c.metadata = metadata c.freeze_version if @frozen @@ -253,51 +215,6 @@ class Chef end end - def load_root_files - select_files_by_glob(File.join(Chef::Util::PathHelper.escape_glob_dir(cookbook_path), "*"), File::FNM_DOTMATCH).each do |file| - file = Chef::Util::PathHelper.cleanpath(file) - next if File.directory?(file) - next if File.basename(file) == UPLOADED_COOKBOOK_VERSION_FILE - name = Chef::Util::PathHelper.relative_path_from(@cookbook_path, file) - cookbook_settings[:root_filenames][name] = file - end - end - - def load_recursively_as(category, category_dir, glob) - glob_pattern = File.join(Chef::Util::PathHelper.escape_glob_dir(cookbook_path, category_dir), "**", glob) - select_files_by_glob(glob_pattern, File::FNM_DOTMATCH).each do |file| - file = Chef::Util::PathHelper.cleanpath(file) - name = Chef::Util::PathHelper.relative_path_from(@cookbook_path, file) - cookbook_settings[category][name] = file - end - end - - def load_as(category, *path_glob) - glob_pattern = File.join(Chef::Util::PathHelper.escape_glob_dir(cookbook_path), *path_glob) - select_files_by_glob(glob_pattern).each do |file| - file = Chef::Util::PathHelper.cleanpath(file) - name = Chef::Util::PathHelper.relative_path_from(@cookbook_path, file) - cookbook_settings[category][name] = file - end - end - - # Mimic Dir.glob inside a cookbook by running `File.fnmatch?` against - # `cookbook_settings[:all_files]`. - # - # @param pattern [String] a glob string passed to `File.fnmatch?` - # @param option [Integer] Option flag to control globbing behavior. These - # are constants defined on `File`, such as `File::FNM_DOTMATCH`. - # `File.fnmatch?` and `Dir.glob` only take one option argument, if you - # need to combine options, you must `|` the constants together. To make - # `File.fnmatch?` behave like `Dir.glob`, `File::FNM_PATHNAME` is - # always enabled. - def select_files_by_glob(pattern, option = 0) - combined_opts = option | File::FNM_PATHNAME - cookbook_settings[:all_files].values.select do |path| - File.fnmatch?(pattern, path, combined_opts) - end - end - def remove_ignored_files cookbook_settings[:all_files].reject! do |relative_path, full_path| chefignore.ignored?(relative_path) diff --git a/lib/chef/cookbook/file_system_file_vendor.rb b/lib/chef/cookbook/file_system_file_vendor.rb index 8088ed00cd..1f43095ea3 100644 --- a/lib/chef/cookbook/file_system_file_vendor.rb +++ b/lib/chef/cookbook/file_system_file_vendor.rb @@ -35,7 +35,7 @@ class Chef attr_reader :repo_paths def initialize(manifest, *repo_paths) - @cookbook_name = manifest[:cookbook_name] + @cookbook_name = manifest.name @repo_paths = repo_paths.flatten raise ArgumentError, "You must specify at least one repo path" if repo_paths.empty? end diff --git a/lib/chef/cookbook/manifest_v0.rb b/lib/chef/cookbook/manifest_v0.rb new file mode 100644 index 0000000000..3e50d86071 --- /dev/null +++ b/lib/chef/cookbook/manifest_v0.rb @@ -0,0 +1,63 @@ +# Author:: Daniel DeLeo (<dan@chef.io>) +# Copyright:: Copyright 2015-2016, Chef Software Inc. +# 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 "chef/json_compat" +require "chef/mixin/versioned_api" + +class Chef + class Cookbook + class ManifestV0 + extend Chef::Mixin::VersionedAPI + + minimum_api_version 0 + + COOKBOOK_SEGMENTS = %w{ resources providers recipes definitions libraries attributes files templates root_files } + + def self.from_hash(hash) + response = Mash.new + response[:all_files] = COOKBOOK_SEGMENTS.inject([]) do |memo, segment| + next memo if hash[segment].nil? || hash[segment].empty? + hash[segment].each do |file| + file["name"] = "#{segment}/#{file["name"]}" unless segment == "root_files" + memo << file + end + memo + end + response + end + + def self.to_hash(manifest) + result = manifest.manifest.dup + result.delete("all_files") + + files = manifest.by_parent_directory + files.keys.inject(result) do |memo, parent| + if COOKBOOK_SEGMENTS.include?(parent) + memo[parent] ||= [] + files[parent].each do |file| + file["name"] = file["name"].split("/")[1] unless parent == "root_files" + file.delete("full_path") + memo[parent] << file + end + end + memo + end + + result.merge({ "frozen?" => manifest.frozen_version?, "chef_type" => "cookbook_version" }) + end + end + end +end diff --git a/lib/chef/cookbook/manifest_v2.rb b/lib/chef/cookbook/manifest_v2.rb new file mode 100644 index 0000000000..59b5c9afb0 --- /dev/null +++ b/lib/chef/cookbook/manifest_v2.rb @@ -0,0 +1,41 @@ +# Copyright:: Copyright 2015-2016, Chef Software Inc. +# 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 "chef/json_compat" +require "chef/mixin/versioned_api" + +class Chef + class Cookbook + class ManifestV2 + extend Chef::Mixin::VersionedAPI + + minimum_api_version 2 + + def self.from_hash(hash) + Chef::Log.debug "processing manifest: #{hash}" + Mash.new hash + end + + def self.to_hash(manifest) + result = manifest.manifest.dup + result["all_files"].map! { |file| file.delete("full_path"); file } + result["frozen?"] = manifest.frozen_version? + result["chef_type"] = "cookbook_version" + result.to_hash + end + + end + end +end diff --git a/lib/chef/cookbook/remote_file_vendor.rb b/lib/chef/cookbook/remote_file_vendor.rb index e63d094dc4..cfd7789311 100644 --- a/lib/chef/cookbook/remote_file_vendor.rb +++ b/lib/chef/cookbook/remote_file_vendor.rb @@ -30,7 +30,7 @@ class Chef def initialize(manifest, rest) @manifest = manifest - @cookbook_name = @manifest[:cookbook_name] || @manifest[:name] + @cookbook_name = @manifest.name @rest = rest end @@ -44,8 +44,8 @@ class Chef raise "get_filename: Cannot determine segment/filename for incoming filename #{filename}" end - raise "No such segment #{segment} in cookbook #{@cookbook_name}" unless @manifest[segment] - found_manifest_record = @manifest[segment].find { |manifest_record| manifest_record[:path] == filename } + raise "No such segment #{segment} in cookbook #{@cookbook_name}" unless @manifest.files_for(segment) + found_manifest_record = @manifest.files_for(segment).find { |manifest_record| manifest_record[:path] == filename } raise "No such file #{filename} in #{@cookbook_name}" unless found_manifest_record cache_filename = File.join("cookbooks", @cookbook_name, found_manifest_record["path"]) diff --git a/lib/chef/cookbook/synchronizer.rb b/lib/chef/cookbook/synchronizer.rb index bb44bc3d5c..625f3b4f20 100644 --- a/lib/chef/cookbook/synchronizer.rb +++ b/lib/chef/cookbook/synchronizer.rb @@ -62,18 +62,11 @@ class Chef # Synchronizes the locally cached copies of cookbooks with the files on the # server. class CookbookSynchronizer - CookbookFile = Struct.new(:cookbook, :segment, :manifest_record) + CookbookFile = Struct.new(:cookbook, :manifest_record) attr_accessor :remove_obsoleted_files def initialize(cookbooks_by_name, events) - @eager_segments = Chef::CookbookVersion::COOKBOOK_SEGMENTS.dup - unless Chef::Config[:no_lazy_load] - @eager_segments.delete(:files) - @eager_segments.delete(:templates) - end - @eager_segments.freeze - @cookbooks_by_name, @events = cookbooks_by_name, events @cookbook_full_file_paths = {} @@ -101,15 +94,19 @@ class Chef end def cookbook_segment(cookbook_name, segment) - @cookbooks_by_name[cookbook_name].manifest[segment] + @cookbooks_by_name[cookbook_name].files_for(segment) end def files + exclude = unless Chef::Config[:no_lazy_load] + [ :files, :templates ] + else + [] + end + @files ||= cookbooks.inject([]) do |memo, cookbook| - @eager_segments.each do |segment| - cookbook.manifest[segment].each do |manifest_record| - memo << CookbookFile.new(cookbook, segment, manifest_record) - end + cookbook.each_file(excluded_parts: exclude) do |manifest_record| + memo << CookbookFile.new(cookbook, manifest_record) end memo end @@ -162,8 +159,10 @@ class Chef @events.cookbook_sync_start(cookbook_count) queue.process(Chef::Config[:cookbook_sync_threads]) + # Ensure that cookbooks know where they're rooted at, for manifest purposes. + ensure_cookbook_paths # Update the full file paths in the manifest - update_cookbook_filenames() + update_cookbook_filenames rescue Exception => e @events.cookbook_sync_failed(cookbooks, e) @@ -176,9 +175,8 @@ class Chef # Saves the full_path to the file of the cookbook to be updated # in the manifest later def save_full_file_path(file, full_path) - @cookbook_full_file_paths[file.cookbook] ||= {} - @cookbook_full_file_paths[file.cookbook][file.segment] ||= [ ] - @cookbook_full_file_paths[file.cookbook][file.segment] << full_path + @cookbook_full_file_paths[file.cookbook] ||= [] + @cookbook_full_file_paths[file.cookbook] << full_path end # remove cookbooks that are not referenced in the expanded run_list at all @@ -229,10 +227,15 @@ class Chef end def update_cookbook_filenames - @cookbook_full_file_paths.each do |cookbook, file_segments| - file_segments.each do |segment, full_paths| - cookbook.replace_segment_filenames(segment, full_paths) - end + @cookbook_full_file_paths.each do |cookbook, full_paths| + cookbook.all_files = full_paths + end + end + + def ensure_cookbook_paths + cookbooks.each do |cookbook| + cb_dir = File.join(Chef::Config[:file_cache_path], "cookbooks", cookbook.name) + cookbook.root_paths = Array(cb_dir) end end diff --git a/lib/chef/cookbook_manifest.rb b/lib/chef/cookbook_manifest.rb index d6de9dd029..125f353d21 100644 --- a/lib/chef/cookbook_manifest.rb +++ b/lib/chef/cookbook_manifest.rb @@ -15,7 +15,10 @@ # limitations under the License. require "forwardable" +require "chef/mixin/versioned_api" require "chef/util/path_helper" +require "chef/cookbook/manifest_v0" +require "chef/cookbook/manifest_v2" require "chef/log" class Chef @@ -24,17 +27,11 @@ class Chef # to a Chef Server. class CookbookManifest - # Duplicates the same constant in CookbookVersion. We cannot remove it - # there because it is treated by other code as part of CookbookVersion's - # public API (also used in some deprecated methods). - COOKBOOK_SEGMENTS = [ :resources, :providers, :recipes, :definitions, :libraries, :attributes, :files, :templates, :root_files ].freeze - extend Forwardable attr_reader :cookbook_version def_delegator :@cookbook_version, :root_paths - def_delegator :@cookbook_version, :segment_filenames def_delegator :@cookbook_version, :name def_delegator :@cookbook_version, :identifier def_delegator :@cookbook_version, :metadata @@ -56,10 +53,7 @@ class Chef # the format used by the `cookbook_artifacts` endpoint (for policyfiles). # Setting this option also changes the behavior of #save_url and # #force_save_url such that CookbookVersions will be uploaded to the new - # `cookbook_artifacts` API. This endpoint is currently under active - # development and the format is expected to change frequently, therefore - # the result of #manifest, #to_hash, and #to_json will not be stable when - # `policy_mode` is enabled. + # `cookbook_artifacts` API. def initialize(cookbook_version, policy_mode: false) @cookbook_version = cookbook_version @policy_mode = !!policy_mode @@ -126,10 +120,7 @@ class Chef end def to_hash - result = manifest.dup - result["frozen?"] = frozen_version? - result["chef_type"] = "cookbook_version" - result.to_hash + CookbookManifestVersions.to_hash(self) end def to_json(*a) @@ -164,15 +155,48 @@ class Chef # make the corresponding changes to the cookbook_version object. Required # to provide backward compatibility with CookbookVersion#manifest= method. def update_from(new_manifest) - @manifest = Mash.new new_manifest + @manifest = Chef::CookbookManifestVersions.from_hash(new_manifest) @checksums = extract_checksums_from_manifest(@manifest) @manifest_records_by_path = extract_manifest_records_by_path(@manifest) + end + + def files_for(part) + return root_files if part.to_s == "root_files" + manifest[:all_files].select do |file| + seg = file[:name].split("/")[0] + part.to_s == seg + end + end + + def each_file(excluded_parts: [], &block) + excluded_parts = Array(excluded_parts).map { |p| p.to_s } - COOKBOOK_SEGMENTS.each do |segment| - next unless @manifest.has_key?(segment) - filenames = @manifest[segment].map { |manifest_record| manifest_record["name"] } + manifest[:all_files].each do |file| + seg = file[:name].split("/")[0] + next if excluded_parts.include?(seg) + yield file if block_given? + end + end + + def by_parent_directory + @by_parent_directory ||= + manifest[:all_files].inject({}) do |memo, file| + parts = file[:name].split("/") + parent = if parts.length == 1 + "root_files" + else + parts[0] + end + + memo[parent] ||= [] + memo[parent] << file + memo + end + end - cookbook_version.replace_segment_filenames(segment, filenames) + def root_files + manifest[:all_files].select do |file| + file[:name].split("/").length == 1 end end @@ -186,15 +210,7 @@ class Chef # See #preferred_manifest_record for a description an individual manifest record. def generate_manifest manifest = Mash.new({ - :recipes => Array.new, - :definitions => Array.new, - :libraries => Array.new, - :attributes => Array.new, - :files => Array.new, - :templates => Array.new, - :resources => Array.new, - :providers => Array.new, - :root_files => Array.new, + all_files: Array.new, }) @checksums = {} @@ -203,24 +219,24 @@ class Chef raise "Cookbook #{name} does not have root_paths! Cannot generate manifest." end - COOKBOOK_SEGMENTS.each do |segment| - segment_filenames(segment).each do |segment_file| - next if File.directory?(segment_file) + @cookbook_version.all_files.each do |file| + next if File.directory?(file) - path, specificity = parse_segment_file_from_root_paths(segment, segment_file) - file_name = File.basename(path) + name, path, specificity = parse_file_from_root_paths(file) - csum = checksum_cookbook_file(segment_file) - @checksums[csum] = segment_file - rs = Mash.new({ - :name => file_name, - :path => path, - :checksum => csum, - :specificity => specificity, - }) + csum = checksum_cookbook_file(file) + @checksums[csum] = file + rs = Mash.new({ + :name => name, + :path => path, + :checksum => csum, + :specificity => specificity, + # full_path is not a part of the normal manifest, but is very useful to keep around. + # uploaders should strip this out. + :full_path => file, + }) - manifest[segment] << rs - end + manifest[:all_files] << rs end manifest[:metadata] = metadata @@ -238,38 +254,42 @@ class Chef @manifest = manifest end - def parse_segment_file_from_root_paths(segment, segment_file) + def parse_file_from_root_paths(file) root_paths.each do |root_path| - pathname = Chef::Util::PathHelper.relative_path_from(root_path, segment_file) + pathname = Chef::Util::PathHelper.relative_path_from(root_path, file) parts = pathname.each_filename.take(2) # Check if path is actually under root_path next if parts[0] == ".." - if segment == :templates || segment == :files + + # if we have a root_file, such as metadata.rb, the first part will be "." + return [ pathname.to_s, pathname.to_s, "default" ] if parts.length == 1 + + segment = parts[0] + + name = File.join(segment, pathname.basename.to_s) + + if segment == "templates" || segment == "files" # Check if pathname looks like files/foo or templates/foo (unscoped) if pathname.each_filename.to_a.length == 2 # Use root_default in case the same path exists at root_default and default - return [ pathname.to_s, "root_default" ] + return [ name, pathname.to_s, "root_default" ] else - return [ pathname.to_s, parts[1] ] + return [ name, pathname.to_s, parts[1] ] end else - return [ pathname.to_s, "default" ] + return [ name, pathname.to_s, "default" ] end end - Chef::Log.error("Cookbook file #{segment_file} not under cookbook root paths #{root_paths.inspect}.") - raise "Cookbook file #{segment_file} not under cookbook root paths #{root_paths.inspect}." + Chef::Log.error("Cookbook file #{file} not under cookbook root paths #{root_paths.inspect}.") + raise "Cookbook file #{file} not under cookbook root paths #{root_paths.inspect}." end def extract_checksums_from_manifest(manifest) - checksums = {} - COOKBOOK_SEGMENTS.each do |segment| - next unless manifest.has_key?(segment) - manifest[segment].each do |manifest_record| - checksums[manifest_record[:checksum]] = nil - end + manifest[:all_files].inject({}) do |memo, manifest_record| + memo[manifest_record[:checksum]] = nil + memo end - checksums end def checksum_cookbook_file(filepath) @@ -277,14 +297,20 @@ class Chef end def extract_manifest_records_by_path(manifest) - manifest_records_by_path = {} - COOKBOOK_SEGMENTS.each do |segment| - next unless manifest.has_key?(segment) - manifest[segment].each do |manifest_record| - manifest_records_by_path[manifest_record[:path]] = manifest_record - end + manifest[:all_files].inject({}) do |memo, manifest_record| + memo[manifest_record[:path]] = manifest_record + memo end - manifest_records_by_path end + + end + class CookbookManifestVersions + + extend Chef::Mixin::VersionedAPIFactory + add_versioned_api_class Chef::Cookbook::ManifestV0 + add_versioned_api_class Chef::Cookbook::ManifestV2 + + def_versioned_delegator :from_hash + def_versioned_delegator :to_hash end end diff --git a/lib/chef/cookbook_site_streaming_uploader.rb b/lib/chef/cookbook_site_streaming_uploader.rb index c0e85ff984..1641992eac 100644 --- a/lib/chef/cookbook_site_streaming_uploader.rb +++ b/lib/chef/cookbook_site_streaming_uploader.rb @@ -43,15 +43,13 @@ class Chef FileUtils.mkdir_p(tmp_cookbook_dir) Chef::Log.debug("Staging at #{tmp_cookbook_dir}") checksums_to_on_disk_paths = cookbook.checksums - Chef::CookbookVersion::COOKBOOK_SEGMENTS.each do |segment| - cookbook.manifest[segment].each do |manifest_record| - path_in_cookbook = manifest_record[:path] - on_disk_path = checksums_to_on_disk_paths[manifest_record[:checksum]] - dest = File.join(tmp_cookbook_dir, cookbook.name.to_s, path_in_cookbook) - FileUtils.mkdir_p(File.dirname(dest)) - Chef::Log.debug("Staging #{on_disk_path} to #{dest}") - FileUtils.cp(on_disk_path, dest) - end + cookbook.each_file do |manifest_record| + path_in_cookbook = manifest_record[:path] + on_disk_path = checksums_to_on_disk_paths[manifest_record[:checksum]] + dest = File.join(tmp_cookbook_dir, cookbook.name.to_s, path_in_cookbook) + FileUtils.mkdir_p(File.dirname(dest)) + Chef::Log.debug("Staging #{on_disk_path} to #{dest}") + FileUtils.cp(on_disk_path, dest) end # First, generate metadata diff --git a/lib/chef/cookbook_uploader.rb b/lib/chef/cookbook_uploader.rb index bb75234563..5e11314190 100644 --- a/lib/chef/cookbook_uploader.rb +++ b/lib/chef/cookbook_uploader.rb @@ -40,7 +40,7 @@ class Chef def initialize(cookbooks, opts = {}) @opts = opts @cookbooks = Array(cookbooks) - @rest = opts[:rest] || Chef::ServerAPI.new(Chef::Config[:chef_server_url]) + @rest = opts[:rest] || Chef::ServerAPI.new(Chef::Config[:chef_server_url], version_class: Chef::CookbookManifestVersions) @concurrency = opts[:concurrency] || 10 @policy_mode = opts[:policy_mode] || false end diff --git a/lib/chef/cookbook_version.rb b/lib/chef/cookbook_version.rb index 7353941bb1..738f98929e 100644 --- a/lib/chef/cookbook_version.rb +++ b/lib/chef/cookbook_version.rb @@ -37,45 +37,23 @@ class Chef class CookbookVersion include Comparable + extend Forwardable + + def_delegator :@cookbook_manifest, :files_for + def_delegator :@cookbook_manifest, :each_file COOKBOOK_SEGMENTS = [ :resources, :providers, :recipes, :definitions, :libraries, :attributes, :files, :templates, :root_files ] - attr_accessor :all_files + attr_reader :all_files attr_accessor :root_paths - attr_accessor :definition_filenames - attr_accessor :template_filenames - attr_accessor :file_filenames - attr_accessor :library_filenames - attr_accessor :resource_filenames - attr_accessor :provider_filenames - attr_accessor :root_filenames attr_accessor :name - attr_accessor :metadata_filenames - - def status=(new_status) - Chef.deprecated(:internal_api, "Deprecated method `status' called. This method will be removed.") - @status = new_status - end - - def status - Chef.deprecated(:internal_api, "Deprecated method `status' called. This method will be removed.") - @status - end # A Chef::Cookbook::Metadata object. It has a setter that fixes up the # metadata to add descriptions of the recipes contained in this # CookbookVersion. attr_reader :metadata - # attribute_filenames also has a setter that has non-default - # functionality. - attr_reader :attribute_filenames - - # recipe_filenames also has a setter that has non-default - # functionality. - attr_reader :recipe_filenames - attr_reader :recipe_filenames_by_name attr_reader :attribute_filenames_by_short_filename @@ -96,6 +74,11 @@ class Chef root_paths[0] end + def all_files=(files) + @all_files = Array(files) + cookbook_manifest.reset! + end + # This is the one and only method that knows how cookbook files' # checksums are generated. def self.checksum_cookbook_file(filepath) @@ -118,23 +101,10 @@ class Chef @root_paths = root_paths @frozen = false - @attribute_filenames = Array.new - @definition_filenames = Array.new - @template_filenames = Array.new - @file_filenames = Array.new - @recipe_filenames = Array.new - @recipe_filenames_by_name = Hash.new - @library_filenames = Array.new - @resource_filenames = Array.new - @provider_filenames = Array.new - @metadata_filenames = Array.new - @root_filenames = Array.new - @all_files = Array.new - # deprecated - @status = :ready @file_vendor = nil + @cookbook_manifest = Chef::CookbookManifest.new(self) @metadata = Chef::Cookbook::Metadata.new @chef_server_rest = chef_server_rest end @@ -163,10 +133,12 @@ class Chef "#{name}-#{version}" end - def attribute_filenames=(*filenames) - @attribute_filenames = filenames.flatten - @attribute_filenames_by_short_filename = filenames_by_name(attribute_filenames) - attribute_filenames + def attribute_filenames_by_short_filename + @attribute_filenames_by_short_filename ||= filenames_by_name(files_for("attributes")) + end + + def recipe_filenames_by_name + @recipe_filenames_by_name ||= filenames_by_name(files_for("recipes")) end def metadata=(metadata) @@ -175,14 +147,14 @@ class Chef @metadata end - ## BACKCOMPAT/DEPRECATED - Remove these and fix breakage before release [DAN - 5/20/2010]## - alias :attribute_files :attribute_filenames - alias :attribute_files= :attribute_filenames= - def manifest cookbook_manifest.manifest end + def manifest=(new_manifest) + cookbook_manifest.update_from(new_manifest) + end + # Returns a hash of checksums to either nil or the on disk path (which is # done by generate_manifest). def checksums @@ -193,29 +165,16 @@ class Chef cookbook_manifest.manifest_records_by_path end - def manifest=(new_manifest) - cookbook_manifest.update_from(new_manifest) - end - # Return recipe names in the form of cookbook_name::recipe_name def fully_qualified_recipe_names - results = Array.new - recipe_filenames_by_name.each_key do |rname| - results << "#{name}::#{rname}" + files_for("recipes").inject([]) do |memo, recipe| + rname = recipe[:name].split("/")[1] + rname = File.basename(rname, ".rb") + memo << "#{name}::#{rname}" + memo end - results end - def recipe_filenames=(*filenames) - @recipe_filenames = filenames.flatten - @recipe_filenames_by_name = filenames_by_name(recipe_filenames) - recipe_filenames - end - - ## BACKCOMPAT/DEPRECATED - Remove these and fix breakage before release [DAN - 5/20/2010]## - alias :recipe_files :recipe_filenames - alias :recipe_files= :recipe_filenames= - # called from DSL def load_recipe(recipe_name, run_context) unless recipe_filenames_by_name.has_key?(recipe_name) @@ -235,41 +194,7 @@ class Chef end def segment_filenames(segment) - unless COOKBOOK_SEGMENTS.include?(segment) - raise ArgumentError, "invalid segment #{segment}: must be one of #{COOKBOOK_SEGMENTS.join(', ')}" - end - - case segment.to_sym - when :resources - @resource_filenames - when :providers - @provider_filenames - when :recipes - @recipe_filenames - when :libraries - @library_filenames - when :definitions - @definition_filenames - when :attributes - @attribute_filenames - when :files - @file_filenames - when :templates - @template_filenames - when :root_files - @root_filenames - end - end - - def replace_segment_filenames(segment, filenames) - case segment.to_sym - when :recipes - self.recipe_filenames = filenames - when :attributes - self.attribute_filenames = filenames - else - segment_filenames(segment).replace(filenames) - end + files_for(segment).map { |f| f["full_path"] || File.join(root_dir, f["path"]) } end # Query whether a template file +template_filename+ is available. File @@ -349,7 +274,7 @@ class Chef filenames_by_pref = Hash.new preferences.each { |pref| filenames_by_pref[pref] = Array.new } - manifest[segment].each do |manifest_record| + files_for(segment).each do |manifest_record| manifest_record_path = manifest_record[:path] # find the NON SPECIFIC filenames, but prefer them by filespecificity. @@ -389,7 +314,7 @@ class Chef records_by_pref = Hash.new preferences.each { |pref| records_by_pref[pref] = Array.new } - manifest[segment].each do |manifest_record| + files_for(segment).each do |manifest_record| manifest_record_path = manifest_record[:path] # extract the preference part from the path. @@ -469,12 +394,22 @@ class Chef end private :preferences_for_path + def display + output = Mash.new + output["cookbook_name"] = name + output["name"] = full_name + output["frozen?"] = frozen_version? + output["metadata"] = metadata.to_hash + output["version"] = version + output.merge(cookbook_manifest.by_parent_directory) + end + def self.from_hash(o) cookbook_version = new(o["cookbook_name"] || o["name"]) # We want the Chef::Cookbook::Metadata object to always be inflated - cookbook_version.metadata = Chef::Cookbook::Metadata.from_hash(o["metadata"]) cookbook_version.manifest = o + cookbook_version.metadata = Chef::Cookbook::Metadata.from_hash(o["metadata"]) cookbook_version.identifier = o["identifier"] if o.key?("identifier") # We don't need the following step when we decide to stop supporting deprecated operators in the metadata (e.g. <<, >>) @@ -488,33 +423,6 @@ class Chef from_hash(o) end - # @deprecated This method was used by the Ruby Chef Server and is no longer - # needed. There is no replacement. - def generate_manifest_with_urls - Chef.deprecated(:internal_api, "Deprecated method #generate_manifest_with_urls.") - - rendered_manifest = manifest.dup - COOKBOOK_SEGMENTS.each do |segment| - if rendered_manifest.has_key?(segment) - rendered_manifest[segment].each do |manifest_record| - url_options = { :cookbook_name => name.to_s, :cookbook_version => version, :checksum => manifest_record["checksum"] } - manifest_record["url"] = yield(url_options) - end - end - end - rendered_manifest - end - - def to_hash - # TODO: this should become deprecated when the API for CookbookManifest becomes stable - cookbook_manifest.to_hash - end - - def to_json(*a) - # TODO: this should become deprecated when the API for CookbookManifest becomes stable - cookbook_manifest.to_json - end - def metadata_json_file File.join(root_paths[0], "metadata.json") end @@ -533,22 +441,12 @@ class Chef # REST API ## - def save_url - # TODO: this should become deprecated when the API for CookbookManifest becomes stable - cookbook_manifest.save_url - end - - def force_save_url - # TODO: this should become deprecated when the API for CookbookManifest becomes stable - cookbook_manifest.force_save_url - end - def chef_server_rest @chef_server_rest ||= chef_server_rest end def self.chef_server_rest - Chef::ServerAPI.new(Chef::Config[:chef_server_url]) + Chef::ServerAPI.new(Chef::Config[:chef_server_url], { version_class: Chef::CookbookManifestVersions }) end def destroy @@ -602,12 +500,12 @@ class Chef Chef::Version.new(version) <=> Chef::Version.new(other.version) end - private - def cookbook_manifest @cookbook_manifest ||= CookbookManifest.new(self) end + private + def find_preferred_manifest_record(node, segment, filename) preferences = preferences_for_path(node, segment, filename) @@ -615,15 +513,21 @@ class Chef preferences.find { |preferred_filename| manifest_records_by_path[preferred_filename] } end - # For each filename, produce a mapping of base filename (i.e. recipe name + # For each manifest record, produce a mapping of base filename (i.e. recipe name + # or attribute file) to on disk location + def relative_paths_by_name(records) + records.select { |record| record[:name] =~ /\.rb$/ }.inject({}) { |memo, record| memo[File.basename(record[:name], ".rb")] = record[:path]; memo } + end + + # For each manifest record, produce a mapping of base filename (i.e. recipe name # or attribute file) to on disk location - def filenames_by_name(filenames) - filenames.select { |filename| filename =~ /\.rb$/ }.inject({}) { |memo, filename| memo[File.basename(filename, ".rb")] = filename; memo } + def filenames_by_name(records) + records.select { |record| record[:name] =~ /\.rb$/ }.inject({}) { |memo, record| memo[File.basename(record[:name], ".rb")] = record[:full_path]; memo } end def file_vendor unless @file_vendor - @file_vendor = Chef::Cookbook::FileVendor.create_from_manifest(manifest) + @file_vendor = Chef::Cookbook::FileVendor.create_from_manifest(cookbook_manifest) end @file_vendor end diff --git a/lib/chef/http/socketless_chef_zero_client.rb b/lib/chef/http/socketless_chef_zero_client.rb index d2f1f45b1d..296330815a 100644 --- a/lib/chef/http/socketless_chef_zero_client.rb +++ b/lib/chef/http/socketless_chef_zero_client.rb @@ -170,6 +170,7 @@ class Chef "QUERY_STRING" => url.query, "SERVER_PORT" => url.port, "HTTP_HOST" => "localhost:#{url.port}", + "HTTP_X_OPS_SERVER_API_VERSION" => headers["X-Ops-Server-API-Version"], "rack.url_scheme" => "chefzero", "rack.input" => StringIO.new(body_str), } diff --git a/lib/chef/knife/cookbook_download.rb b/lib/chef/knife/cookbook_download.rb index 741f444093..b745e77f27 100644 --- a/lib/chef/knife/cookbook_download.rb +++ b/lib/chef/knife/cookbook_download.rb @@ -70,7 +70,7 @@ class Chef ui.info("Downloading #{@cookbook_name} cookbook version #{@version}") cookbook = Chef::CookbookVersion.load(@cookbook_name, @version) - manifest = cookbook.manifest + manifest = cookbook.cookbook_manifest basedir = File.join(config[:download_directory], "#{@cookbook_name}-#{cookbook.version}") if File.exists?(basedir) @@ -83,10 +83,9 @@ class Chef end end - Chef::CookbookVersion::COOKBOOK_SEGMENTS.each do |segment| - next unless manifest.has_key?(segment) + manifest.by_parent_directory.each do |segment, files| ui.info("Downloading #{segment}") - manifest[segment].each do |segment_file| + files.each do |segment_file| dest = File.join(basedir, segment_file["path"].gsub("/", File::SEPARATOR)) Chef::Log.debug("Downloading #{segment_file['path']} to #{dest}") FileUtils.mkdir_p(File.dirname(dest)) diff --git a/lib/chef/knife/cookbook_show.rb b/lib/chef/knife/cookbook_show.rb index d0c930de0a..1d9983632d 100644 --- a/lib/chef/knife/cookbook_show.rb +++ b/lib/chef/knife/cookbook_show.rb @@ -76,9 +76,13 @@ class Chef pretty_print(temp_file.read) when 3 # We are showing a specific part of the cookbook - output(cookbook.manifest[segment]) - when 2 # We are showing the whole cookbook data - output(cookbook) + if segment == "metadata" + output(cookbook.metadata) + else + output(cookbook.files_for(segment)) + end + when 2 # We are showing the whole cookbook + output(cookbook.display) when 1 # We are showing the cookbook versions (all of them) env = config[:environment] api_endpoint = env ? "environments/#{env}/cookbooks/#{cookbook_name}" : "cookbooks/#{cookbook_name}" diff --git a/lib/chef/policy_builder/expand_node_object.rb b/lib/chef/policy_builder/expand_node_object.rb index dbed44a002..26f39e8b73 100644 --- a/lib/chef/policy_builder/expand_node_object.rb +++ b/lib/chef/policy_builder/expand_node_object.rb @@ -239,7 +239,8 @@ class Chef end def api_service - @api_service ||= Chef::ServerAPI.new(config[:chef_server_url]) + @api_service ||= Chef::ServerAPI.new(config[:chef_server_url], + { version_class: Chef::CookbookManifestVersions }) end def config diff --git a/lib/chef/policy_builder/policyfile.rb b/lib/chef/policy_builder/policyfile.rb index f0009eac6c..f84e1dc68e 100644 --- a/lib/chef/policy_builder/policyfile.rb +++ b/lib/chef/policy_builder/policyfile.rb @@ -149,7 +149,7 @@ class Chef # # @return [Chef::RunContext] def setup_run_context(specific_recipes = nil) - Chef::Cookbook::FileVendor.fetch_from_remote(http_api) + Chef::Cookbook::FileVendor.fetch_from_remote(api_service) sync_cookbooks cookbook_collection = Chef::CookbookCollection.new(cookbooks_to_sync) cookbook_collection.validate! @@ -267,7 +267,7 @@ class Chef # @api private def policy - @policy ||= http_api.get(policyfile_location) + @policy ||= api_service.get(policyfile_location) rescue Net::HTTPServerException => e raise ConfigurationError, "Error loading policyfile from `#{policyfile_location}': #{e.class} - #{e.message}" end @@ -452,8 +452,9 @@ class Chef end # @api private - def http_api - @api_service ||= Chef::ServerAPI.new(config[:chef_server_url]) + def api_service + @api_service ||= Chef::ServerAPI.new(config[:chef_server_url], + { version_class: Chef::CookbookManifestVersions }) end # @api private @@ -496,7 +497,7 @@ class Chef def compat_mode_manifest_for(cookbook_name, lock_data) xyz_version = lock_data["dotted_decimal_identifier"] rel_url = "cookbooks/#{cookbook_name}/#{xyz_version}" - inflate_cbv_object(http_api.get(rel_url)) + inflate_cbv_object(api_service.get(rel_url)) rescue Exception => e message = "Error loading cookbook #{cookbook_name} at version #{xyz_version} from #{rel_url}: #{e.class} - #{e.message}" err = Chef::Exceptions::CookbookNotFound.new(message) @@ -507,7 +508,7 @@ class Chef def artifact_manifest_for(cookbook_name, lock_data) identifier = lock_data["identifier"] rel_url = "cookbook_artifacts/#{cookbook_name}/#{identifier}" - inflate_cbv_object(http_api.get(rel_url)) + inflate_cbv_object(api_service.get(rel_url)) rescue Exception => e message = "Error loading cookbook #{cookbook_name} with identifier #{identifier} from #{rel_url}: #{e.class} - #{e.message}" err = Chef::Exceptions::CookbookNotFound.new(message) diff --git a/lib/chef/run_context/cookbook_compiler.rb b/lib/chef/run_context/cookbook_compiler.rb index b2a8d236a3..94635be03d 100644 --- a/lib/chef/run_context/cookbook_compiler.rb +++ b/lib/chef/run_context/cookbook_compiler.rb @@ -268,7 +268,7 @@ class Chef # Lists the local paths to files in +cookbook+ of type +segment+ # (attribute, recipe, etc.), sorted lexically. def files_in_cookbook_by_segment(cookbook, segment) - cookbook_collection[cookbook].segment_filenames(segment).sort + cookbook_collection[cookbook].files_for(segment).map { |record| record[:full_path] }.sort end # Yields the name, as a symbol, of each cookbook depended on by |