class Chef::Knife::CookbookUpload
Public Instance Methods
cookbook_repo()
click to toggle source
# File lib/chef/knife/cookbook_upload.rb, line 212 def cookbook_repo @cookbook_loader ||= begin Chef::Cookbook::FileVendor.fetch_from_disk(config[:cookbook_path]) Chef::CookbookLoader.new(config[:cookbook_path]) end end
cookbooks_to_upload()
click to toggle source
# File lib/chef/knife/cookbook_upload.rb, line 189 def cookbooks_to_upload @cookbooks_to_upload ||= if config[:all] cookbook_repo.load_cookbooks else upload_set = {} @name_args.each do |cookbook_name| unless upload_set.key?(cookbook_name) upload_set[cookbook_name] = cookbook_repo[cookbook_name] if config[:depends] upload_set[cookbook_name].metadata.dependencies.each_key { |dep| @name_args << dep } end end rescue Exceptions::CookbookNotFoundInRepo => e ui.error(e.message) Log.debug(e) end upload_set end end
environment()
click to toggle source
# File lib/chef/knife/cookbook_upload.rb, line 226 def environment @environment ||= config[:environment] ? Environment.load(config[:environment]) : nil end
justify_width()
click to toggle source
# File lib/chef/knife/cookbook_upload.rb, line 172 def justify_width @justify_width ||= server_side_cookbooks.map(&:size).max.to_i + 2 end
left_justify_name(cookbook)
click to toggle source
@param cookbook [Chef::CookbookVersion]
# File lib/chef/knife/cookbook_upload.rb, line 179 def left_justify_name(cookbook) # We only want to lookup justify width value if we're already loading # cookbooks to check dependencies exist in Chef Infra Server. if config[:check_dependencies] == true cookbook.name.to_s.ljust(justify_width + 10) else cookbook.name.to_s.ljust(24) end end
run()
click to toggle source
# File lib/chef/knife/cookbook_upload.rb, line 79 def run # Sanity check before we load anything from the server if ! config[:all] && @name_args.empty? show_usage ui.fatal("You must specify the --all flag or at least one cookbook name") exit 1 end config[:cookbook_path] ||= Chef::Config[:cookbook_path] assert_environment_valid! version_constraints_to_update = {} upload_failures = 0 upload_ok = 0 cookbooks = [] cookbooks_to_upload.each do |cookbook_name, cookbook| raise Chef::Exceptions::MetadataNotFound.new(cookbook.root_paths[0], cookbook_name) unless cookbook.has_metadata_file? if cookbook.metadata.name.nil? message = "Cookbook loaded at path [#{cookbook.root_paths[0]}] has invalid metadata: #{cookbook.metadata.errors.join("; ")}" raise Chef::Exceptions::MetadataNotValid, message end cookbooks << cookbook end if cookbooks.empty? cookbook_path = config[:cookbook_path].respond_to?(:join) ? config[:cookbook_path].join(", ") : config[:cookbook_path] ui.warn("Could not find any cookbooks in your cookbook path: '#{File.expand_path(cookbook_path)}'. Use --cookbook-path to specify the desired path.") else Chef::CookbookLoader.copy_to_tmp_dir_from_array(cookbooks) do |tmp_cl| tmp_cl.load_cookbooks tmp_cl.compile_metadata tmp_cl.freeze_versions if config[:freeze] cookbooks_for_upload = [] tmp_cl.each do |cookbook_name, cookbook| cookbooks_for_upload << cookbook version_constraints_to_update[cookbook_name] = cookbook.version end if config[:all] if cookbooks_for_upload.any? begin upload(cookbooks_for_upload) rescue Chef::Exceptions::CookbookFrozen ui.warn("Not updating version constraints for some cookbooks in the environment as the cookbook is frozen.") ui.error("Uploading of some of the cookbooks must be failed. Remove cookbook whose version is frozen from your cookbooks repo OR use --force option.") upload_failures += 1 rescue SystemExit => e raise exit e.status end ui.info("Uploaded all cookbooks.") if upload_failures == 0 end else tmp_cl.each do |cookbook_name, cookbook| upload([cookbook]) upload_ok += 1 rescue Exceptions::CookbookNotFoundInRepo => e upload_failures += 1 ui.error("Could not find cookbook #{cookbook_name} in your cookbook path, skipping it") Log.debug(e) upload_failures += 1 rescue Exceptions::CookbookFrozen ui.warn("Not updating version constraints for #{cookbook_name} in the environment as the cookbook is frozen.") upload_failures += 1 rescue SystemExit => e raise exit e.status end if upload_failures == 0 ui.info "Uploaded #{upload_ok} cookbook#{upload_ok == 1 ? "" : "s"}." elsif upload_failures > 0 && upload_ok > 0 ui.warn "Uploaded #{upload_ok} cookbook#{upload_ok == 1 ? "" : "s"} ok but #{upload_failures} " + "cookbook#{upload_failures == 1 ? "" : "s"} upload failed." elsif upload_failures > 0 && upload_ok == 0 ui.error "Failed to upload #{upload_failures} cookbook#{upload_failures == 1 ? "" : "s"}." exit 1 end end unless version_constraints_to_update.empty? update_version_constraints(version_constraints_to_update) if config[:environment] end end end end
server_side_cookbooks()
click to toggle source
# File lib/chef/knife/cookbook_upload.rb, line 168 def server_side_cookbooks @server_side_cookbooks ||= Chef::CookbookVersion.list_all_versions end
update_version_constraints(new_version_constraints)
click to toggle source
# File lib/chef/knife/cookbook_upload.rb, line 219 def update_version_constraints(new_version_constraints) new_version_constraints.each do |cookbook_name, version| environment.cookbook_versions[cookbook_name] = "= #{version}" end environment.save end
Private Instance Methods
assert_environment_valid!()
click to toggle source
# File lib/chef/knife/cookbook_upload.rb, line 232 def assert_environment_valid! environment rescue Net::HTTPClientException => e if e.response.code.to_s == "404" ui.error "The environment #{config[:environment]} does not exist on the server, aborting." Log.debug(e) exit 1 else raise end end
check_for_broken_links!(cookbook)
click to toggle source
# File lib/chef/knife/cookbook_upload.rb, line 256 def check_for_broken_links!(cookbook) # MUST!! dup the cookbook version object--it memoizes its # manifest object, but the manifest becomes invalid when you # regenerate the metadata broken_files = cookbook.dup.manifest_records_by_path.select do |path, info| !/[0-9a-f]{32,}/.match?(info["checksum"]) end unless broken_files.empty? broken_filenames = Array(broken_files).map { |path, info| path } ui.error "The cookbook #{cookbook.name} has one or more broken files" ui.error "This is probably caused by broken symlinks in the cookbook directory" ui.error "The broken file(s) are: #{broken_filenames.join(" ")}" exit 1 end end
check_for_dependencies!(cookbook)
click to toggle source
# File lib/chef/knife/cookbook_upload.rb, line 272 def check_for_dependencies!(cookbook) # for all dependencies, check if the version is on the server, or # the version is in the cookbooks being uploaded. If not, exit and warn the user. missing_dependencies = cookbook.metadata.dependencies.reject do |cookbook_name, version| check_server_side_cookbooks(cookbook_name, version) || check_uploading_cookbooks(cookbook_name, version) end unless missing_dependencies.empty? missing_cookbook_names = missing_dependencies.map { |cookbook_name, version| "'#{cookbook_name}' version '#{version}'" } ui.error "Cookbook #{cookbook.name} depends on cookbooks which are not currently" ui.error "being uploaded and cannot be found on the server." ui.error "The missing cookbook(s) are: #{missing_cookbook_names.join(", ")}" exit 1 end end
check_server_side_cookbooks(cookbook_name, version)
click to toggle source
# File lib/chef/knife/cookbook_upload.rb, line 288 def check_server_side_cookbooks(cookbook_name, version) if server_side_cookbooks[cookbook_name].nil? false else versions = server_side_cookbooks[cookbook_name]["versions"].collect { |versions| versions["version"] } Log.debug "Versions of cookbook '#{cookbook_name}' returned by the server: #{versions.join(", ")}" server_side_cookbooks[cookbook_name]["versions"].each do |versions_hash| if Chef::VersionConstraint.new(version).include?(versions_hash["version"]) Log.debug "Matched cookbook '#{cookbook_name}' with constraint '#{version}' to cookbook version '#{versions_hash["version"]}' on the server" return true end end false end end
check_uploading_cookbooks(cookbook_name, version)
click to toggle source
# File lib/chef/knife/cookbook_upload.rb, line 304 def check_uploading_cookbooks(cookbook_name, version) if (! cookbooks_to_upload[cookbook_name].nil?) && Chef::VersionConstraint.new(version).include?(cookbooks_to_upload[cookbook_name].version) Log.debug "Matched cookbook '#{cookbook_name}' with constraint '#{version}' to a local cookbook." return true end false end
upload(cookbooks)
click to toggle source
# File lib/chef/knife/cookbook_upload.rb, line 244 def upload(cookbooks) cookbooks.each do |cb| ui.info("Uploading #{left_justify_name(cb)} [#{cb.version}]") check_for_broken_links!(cb) check_for_dependencies!(cb) if config[:check_dependencies] == true end Chef::CookbookUploader.new(cookbooks, force: config[:force], concurrency: config[:concurrency]).upload_cookbooks rescue Chef::Exceptions::CookbookFrozen => e ui.error e raise end