def download_cookbook(root_dir, cookbook)
      cache_dir = File.join(AgentConfig.cache_dir, "right_link", "cookbooks")
      cookbook_tarball = File.join(cache_dir, "#{cookbook.hash.split('?').first}.tar")
      begin
        FileUtils.mkdir_p(cache_dir)
        File.open(cookbook_tarball, "ab") do |tarball|
          if tarball.stat.size == 0
            #audit cookbook name & part of hash (as a disambiguator)
            name = cookbook.name ; tag  = cookbook.hash[0..4]
            @audit.append_info("Downloading cookbook '#{name}' (#{tag})")
            @downloader.download("/cookbooks/#{cookbook.hash}") do |response|
              tarball << response
            end
            @audit.append_info(@downloader.details)
          end
        end
      rescue Exception => e
        File.unlink(cookbook_tarball) if File.exists?(cookbook_tarball)
        raise
      end

      @audit.append_info("Success; unarchiving cookbook")

      # The local basedir is the faux "repository root" into which we extract all related
      # cookbooks in that set, "related" meaning a set of cookbooks that originally came
      # from the same Chef cookbooks repository as observed by the scraper.
      #
      # Even though we are pulling individually-packaged cookbooks and not the whole repository,
      # we preserve the position of cookbooks in the directory hierarchy such that a given cookbook
      # has the same path relative to the local basedir as the original cookbook had relative to the
      # base directory of its repository.
      #
      # This ensures we will be able to deal with future changes to the Chef merge algorithm,
      # as well as accommodate "naughty" cookbooks that side-load data from the filesystem
      # using relative paths to other cookbooks.
      FileUtils.mkdir_p(root_dir)
      Dir.chdir(root_dir) do
        # note that Windows uses a "tar.cmd" file which is found via the PATH
        # used by the command interpreter.
        cmd = "tar xf #{cookbook_tarball.inspect} 2>&1"
        Log.debug(cmd)
        output = `#{cmd}`
        @audit.append_info(output)
        unless $?.success?
          report_failure("Unknown error", SubprocessFormatting.reason($?))
        end
      end
      return true
    end
def download_cookbook(root_dir, cookbook)
      cache_dir = File.join(AgentConfig.cache_dir, "right_link", "cookbooks")
      cookbook_tarball = File.join(cache_dir, "#{cookbook.hash.split('?').first}.tar")
      begin
        FileUtils.mkdir_p(cache_dir)
        File.open(cookbook_tarball, "ab") do |tarball|
          if tarball.stat.size == 0
            #audit cookbook name & part of hash (as a disambiguator)
            name = cookbook.name ; tag  = cookbook.hash[0..4]
            @audit.append_info("Downloading cookbook '#{name}' (#{tag})")
            @downloader.download("/cookbooks/#{cookbook.hash}") do |response|
              tarball << response
            end
            @audit.append_info(@downloader.details)
          end
        end
      rescue Exception => e
        File.unlink(cookbook_tarball) if File.exists?(cookbook_tarball)
        raise
      end

      @audit.append_info("Success; unarchiving cookbook")

      # The local basedir is the faux "repository root" into which we extract all related
      # cookbooks in that set, "related" meaning a set of cookbooks that originally came
      # from the same Chef cookbooks repository as observed by the scraper.
      #
      # Even though we are pulling individually-packaged cookbooks and not the whole repository,
      # we preserve the position of cookbooks in the directory hierarchy such that a given cookbook
      # has the same path relative to the local basedir as the original cookbook had relative to the
      # base directory of its repository.
      #
      # This ensures we will be able to deal with future changes to the Chef merge algorithm,
      # as well as accommodate "naughty" cookbooks that side-load data from the filesystem
      # using relative paths to other cookbooks.
      FileUtils.mkdir_p(root_dir)
      Dir.chdir(root_dir) do
        # note that Windows uses a "tar.cmd" file which is found via the PATH
        # used by the command interpreter.
        cmd = "tar xf #{cookbook_tarball.inspect} 2>&1"
        Log.debug(cmd)
        output = `#{cmd}`
        @audit.append_info(output)
        unless $?.success?
          report_failure("Unknown error", SubprocessFormatting.reason($?))
        end
      end
      return true
    end
Download a cookbook from Repose mirror and extract it to the filesystem.

 === Parameters
 root_dir(String):: subdir of basedir into which this cookbook goes
 cookbook(Cookbook):: cookbook

 === Raise
 Propagates exceptions raised by callees, namely DownloadFailure
 and ReposeServerFailure

 === Return
 true:: always returns true