class Chef::Knife::CookbookDownload

Attributes

cookbook_name[RW]
version[R]

Public Instance Methods

ask_which_version() click to toggle source
# File lib/chef/knife/cookbook_download.rb, line 123
def ask_which_version
  question = "Which version do you want to download?\n"
  valid_responses = {}
  available_versions.each_with_index do |version, index|
    valid_responses[(index + 1).to_s] = version
    question << "#{index + 1}. #{@cookbook_name} #{version}\n"
  end
  question += "\n"
  response = ask_question(question).strip

  unless @version = valid_responses[response]
    ui.error("'#{response}' is not a valid value.")
    exit(1)
  end
  @version
end
available_versions() click to toggle source
# File lib/chef/knife/cookbook_download.rb, line 111
def available_versions
  @available_versions ||= begin
    versions = Chef::CookbookVersion.available_versions(@cookbook_name)
    unless versions.nil?
      versions.map! { |version| Chef::Version.new(version) }
      versions.sort!
    end
    versions
  end
  @available_versions
end
determine_version() click to toggle source
# File lib/chef/knife/cookbook_download.rb, line 99
def determine_version
  if available_versions.nil?
    nil
  elsif available_versions.size == 1
    @version = available_versions.first
  elsif config[:latest]
    @version = available_versions.last
  else
    ask_which_version
  end
end
run() click to toggle source

TODO: tim/cw: 5-23-2010: need to implement knife-side specificity for downloads - need to implement –platform and –fqdn here

# File lib/chef/knife/cookbook_download.rb, line 55
def run
  @cookbook_name, @version = @name_args

  if @cookbook_name.nil?
    show_usage
    ui.fatal("You must specify a cookbook name")
    exit 1
  elsif @version.nil?
    @version = determine_version
    if @version.nil?
      ui.fatal("No such cookbook found")
      exit 1
    end
  end

  ui.info("Downloading #{@cookbook_name} cookbook version #{@version}")

  cookbook = Chef::CookbookVersion.load(@cookbook_name, @version)
  manifest = cookbook.cookbook_manifest

  basedir = File.join(config[:download_directory], "#{@cookbook_name}-#{cookbook.version}")
  if File.exists?(basedir)
    if config[:force]
      Chef::Log.trace("Deleting #{basedir}")
      FileUtils.rm_rf(basedir)
    else
      ui.fatal("Directory #{basedir} exists, use --force to overwrite")
      exit
    end
  end

  manifest.by_parent_directory.each do |segment, files|
    ui.info("Downloading #{segment}")
    files.each do |segment_file|
      dest = File.join(basedir, segment_file["path"].gsub("/", File::SEPARATOR))
      Chef::Log.trace("Downloading #{segment_file['path']} to #{dest}")
      FileUtils.mkdir_p(File.dirname(dest))
      tempfile = rest.streaming_request(segment_file["url"])
      FileUtils.mv(tempfile.path, dest)
    end
  end
  ui.info("Cookbook downloaded to #{basedir}")
end