class Berkshelf::CommunityREST
Constants
- V1_API
Attributes
@return [String]
@return [Berkshelf::RidleyCompat]
@return [Integer]
how many retries to attempt on HTTP requests
@return [Float]
time to wait between retries
Public Class Methods
@param [String] uri (CommunityREST::V1_API)
location of community site to connect to
@option options [Integer] :retries (5)
retry requests on 5XX failures
@option options [Float] :retry_interval (0.5)
how often we should pause between retries
# File lib/berkshelf/community_rest.rb, line 70 def initialize(uri = V1_API, options = {}) options = options.dup options = { retries: 5, retry_interval: 0.5, ssl: Berkshelf::Config.instance.ssl }.merge(options) @api_uri = uri options[:server_url] = uri @retries = options.delete(:retries) @retry_interval = options.delete(:retry_interval) @connection = Berkshelf::RidleyCompatJSON.new(**options) end
@param [String] target
file path to the tar.gz archive on disk
@param [String] destination
file path to extract the contents of the target to
@return [String]
# File lib/berkshelf/community_rest.rb, line 13 def unpack(target, destination) if is_gzip_file(target) || is_tar_file(target) Mixlib::Archive.new(target).extract(destination) else raise Berkshelf::UnknownCompressionType.new(target, destination) end destination end
@param [String] version
@return [String]
# File lib/berkshelf/community_rest.rb, line 26 def uri_escape_version(version) version.to_s.tr(".", "_") end
@param [String] uri
@return [String]
# File lib/berkshelf/community_rest.rb, line 33 def version_from_uri(uri) File.basename(uri.to_s).tr("_", ".") end
Private Class Methods
# File lib/berkshelf/community_rest.rb, line 39 def is_gzip_file(path) # You cannot write "\x1F\x8B" because the default encoding of # ruby >= 1.9.3 is UTF-8 and 8B is an invalid in UTF-8. IO.binread(path, 2) == [0x1F, 0x8B].pack("C*") end
# File lib/berkshelf/community_rest.rb, line 45 def is_tar_file(path) IO.binread(path, 8, 257).to_s == "ustar\x0000" end
Public Instance Methods
Download and extract target cookbook archive to the local file system, returning its filepath.
@param [String] name
the name of the cookbook
@param [String] version
the targeted version of the cookbook
@return [String, nil]
cookbook filepath, or nil if archive does not contain a cookbook
# File lib/berkshelf/community_rest.rb, line 91 def download(name, version) archive = stream(find(name, version)["file"]) scratch = Dir.mktmpdir extracted = self.class.unpack(archive.path, scratch) if File.cookbook?(extracted) extracted else Dir.glob("#{extracted}/*").find do |dir| File.cookbook?(dir) end end ensure archive.unlink unless archive.nil? end
# File lib/berkshelf/community_rest.rb, line 107 def find(name, version) body = connection.get("cookbooks/#{name}/versions/#{self.class.uri_escape_version(version)}") # Artifactory responds with a 200 and blank body for unknown cookbooks. raise CookbookNotFound.new(name, nil, "at `#{api_uri}'") if body.nil? body rescue CookbookNotFound raise rescue Berkshelf::APIClient::ServiceNotFound raise CookbookNotFound.new(name, nil, "at `#{api_uri}'") rescue raise CommunitySiteError.new(api_uri, "'#{name}' (#{version})") end
Returns the latest version of the cookbook and its download link.
@return [String]
# File lib/berkshelf/community_rest.rb, line 125 def latest_version(name) body = connection.get("cookbooks/#{name}") # Artifactory responds with a 200 and blank body for unknown cookbooks. raise CookbookNotFound.new(name, nil, "at `#{api_uri}'") if body.nil? self.class.version_from_uri body["latest_version"] rescue Berkshelf::APIClient::ServiceNotFound raise CookbookNotFound.new(name, nil, "at `#{api_uri}'") rescue raise CommunitySiteError.new(api_uri, "the latest version of '#{name}'") end
@param [String] name @param [String, Semverse::Constraint] constraint
@return [String]
# File lib/berkshelf/community_rest.rb, line 161 def satisfy(name, constraint) Semverse::Constraint.satisfy_best(constraint, versions(name)).to_s rescue Semverse::NoSolutionError nil end
Stream the response body of a remote URL to a file on the local file system
@param [String] target
a URL to stream the response body from
@return [Tempfile]
# File lib/berkshelf/community_rest.rb, line 173 def stream(target) local = Tempfile.new("community-rest-stream") local.binmode Retryable.retryable(tries: retries, on: Berkshelf::APIClientError, sleep: retry_interval) do connection.streaming_request(target, {}, local) end ensure local.close(false) unless local.nil? end
@param [String] name
@return [Array]
# File lib/berkshelf/community_rest.rb, line 141 def versions(name) body = connection.get("cookbooks/#{name}") # Artifactory responds with a 200 and blank body for unknown cookbooks. raise CookbookNotFound.new(name, nil, "at `#{api_uri}'") if body.nil? body["versions"].collect do |version_uri| self.class.version_from_uri(version_uri) end rescue Berkshelf::APIClient::ServiceNotFound raise CookbookNotFound.new(name, nil, "at `#{api_uri}'") rescue raise CommunitySiteError.new(api_uri, "versions of '#{name}'") end