class Chef::Knife::CookbookTarUpload
Public Class Methods
upload_cookbooks(tar_file)
click to toggle source
# File lib/chef/knife/cookbook_tar_upload.rb, line 32 def self.upload_cookbooks(tar_file) # This is the list of cookbooks and their groupings, we upload all the cookbooks in a group at a time cookbook_upload_groups = Array.new cookbook_paths = tar_file.cookbooks cookbook_group_index = 0 total_cookbooks = cookbook_paths.length # Since we now allow you to upload multiple versions of the same cookbook we have to be smart about how we upload the cookbooks # If we upload a cookbook without the proper dependency we will get errors # So the strategy is to categorize cookbooks into groups based on their dependencies and what has been uploaded # Then move the cookbooks to a tmp directory (renaming their directories if necessary) and upload each group in order while !cookbook_paths.empty? cookbook_upload_groups.push(Array.new) # An array of current cookbook names we are uploading. This is used to ensure we dont upload the same cookbook # (different version) in the same group cookbookNamesToUpload = Array.new cookbook_paths.each do |cookbook_path| cookbookName = CookbookTarUpload.get_cookbook_name_from_path cookbook_path # Verify we aren't uploading another version of the cookbook in this group unless cookbookNamesToUpload.index(cookbookName) # Check the cookbook has no dependencies or its dependencies have been uploaded md = Chef::Cookbook::Metadata.new md.from_file File.join(cookbook_path, "metadata.rb") uploadable = true md.dependencies.each do |cookbook_dependency, version_constraint| # Verify we have uploaded the specific cookbook / version unless CookbookTarUpload.is_dependency_uploaded? cookbook_dependency, version_constraint, cookbook_upload_groups ui.error "Cookbook #{cookbookName} depends on cookbook '#{cookbook_dependency}' version '#{version_constraint}'," ui.error "which is not currently being uploaded and cannot be found on the server." uploadable = false break end end if uploadable # Add the cookbook to the group cookbook_upload_groups[cookbook_group_index].push cookbook_path # Add the cookbook's name to our list cookbookNamesToUpload.push(cookbookName) end end end # If we still have cookbooks that need to find a group but we did not add any to this group # we have an error. This can be caused by a missing dependency or a circular dependency. if cookbookNamesToUpload.empty? raise "Unable to upload cookbooks" end # Remove the cookbooks we have added to this group cookbook_upload_groups[cookbook_group_index].each do |cookbook_path| cookbook_paths.delete cookbook_path end cookbook_group_index+=1 end puts "#{total_cookbooks} cookbooks have been grouped into #{cookbook_upload_groups.length} groups" puts "Uploading cookbooks ..." # Upload all cookbooks one group at a time cookbook_upload_groups.each do |cookbookGroup| cookbookTmpPath = ::TmpDirectory.new("cookbooks").path # Move cookbooks to tmp directory and rename if necessary cookbookGroup.each do |cookbook_path| FileUtils.cp_r cookbook_path, File.join(cookbookTmpPath, CookbookTarUpload.get_cookbook_name_from_path(cookbook_path)) end #Upload cookbook group cookbookUploader = Chef::Knife::CookbookUpload.new cookbookUploader.config[:cookbook_path] = cookbookTmpPath cookbookUploader.config[:all] = true cookbookUploader.run end end
Private Class Methods
current_cookbooks()
click to toggle source
# File lib/chef/knife/cookbook_tar_upload.rb, line 169 def self.current_cookbooks unless @@current_cookbooks rest = Chef::REST.new(Chef::Config[:chef_server_url]) @@current_cookbooks = rest.get_rest('cookbooks?num_versions=all') end @@current_cookbooks end
get_cookbook_name_from_path(path)
click to toggle source
Returns the name of the cookbook from its path which could include its version information (i.e. /var/chef/cookbooks/myCookbook-1.0.0 would return myCookbook)
# File lib/chef/knife/cookbook_tar_upload.rb, line 128 def self.get_cookbook_name_from_path path directory = File.basename(path) index = directory =~ /(-[\d]+.[\d]+\.[\d]+\z|-[\d]+\.[\d]+\z)/ if index!=nil return directory[0, index] end directory end
is_dependency_uploaded?(cookbook_dependency, version_constraint, cookbook_upload_groups)
click to toggle source
Given a cookbook's dependency information, and the current cookbooks that will be uploaded, determine if we have uploaded a valid version of that cookbook
# File lib/chef/knife/cookbook_tar_upload.rb, line 139 def self.is_dependency_uploaded? cookbook_dependency, version_constraint, cookbook_upload_groups vc = Chef::VersionConstraint.new(version_constraint) cookbook_upload_groups.each do |cookbook_group| cookbook_group.each do |cookbook_path| if CookbookTarUpload.get_cookbook_name_from_path(cookbook_path)==cookbook_dependency # Get the version of the cookbook that is already in a group md = Chef::Cookbook::Metadata.new md.from_file File.join(cookbook_path, "metadata.rb") if vc.include? md.version return true end end end end # The dependency we are wanting is not part of an upload group so check if it already exists on the chef-server if CookbookTarUpload.current_cookbooks.has_key? cookbook_dependency CookbookTarUpload.current_cookbooks[cookbook_dependency].each do |cookbookVersions| CookbookTarUpload.current_cookbooks[cookbook_dependency]["versions"].each do |cookbookVersion| if vc.include? cookbookVersion["version"] return true end end end end false end
Public Instance Methods
run()
click to toggle source
This method will be executed when you run this knife command.
# File lib/chef/knife/cookbook_tar_upload.rb, line 19 def run if @name_args.size != 1 ui.info("Please specify a tarPath") show_usage exit 1 end tar_file = Chef::TarFile.new(@name_args.first) CookbookTarUpload.upload_cookbooks tar_file end