Class: Berkshelf::CommunityREST

Inherits:
Faraday::Connection
  • Object
show all
Defined in:
lib/berkshelf/community_rest.rb

Constant Summary collapse

V1_API =
'http://cookbooks.opscode.com/api/v1/cookbooks'.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(uri = V1_API, options = {}) ⇒ CommunityREST

Returns a new instance of CommunityREST.

Parameters:

  • uri (String) (defaults to: V1_API)

    (CommunityREST::V1_API) location of community site to connect to

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :retries (Integer) — default: 5

    retry requests on 5XX failures

  • :retry_interval (Float) — default: 0.5

    how often we should pause between retries



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/berkshelf/community_rest.rb', line 77

def initialize(uri = V1_API, options = {})
  options         = options.reverse_merge(retries: 5, retry_interval: 0.5)
  @api_uri        = Addressable::URI.parse(uri)
  @retries        = options[:retries]
  @retry_interval = options[:retry_interval]

  builder = Faraday::Builder.new do |b|
    b.response :parse_json
    b.response :follow_redirects

    b.request :retry,
      max: @retries,
      interval: @retry_interval,
      exceptions: [Faraday::Error::TimeoutError]

    b.adapter :net_http
  end

  super(api_uri, builder: builder)
end

Instance Attribute Details

#api_uriString (readonly)

Returns:



62
63
64
# File 'lib/berkshelf/community_rest.rb', line 62

def api_uri
  @api_uri
end

#retriesInteger (readonly)

Returns how many retries to attempt on HTTP requests.

Returns:

  • (Integer)

    how many retries to attempt on HTTP requests



65
66
67
# File 'lib/berkshelf/community_rest.rb', line 65

def retries
  @retries
end

#retry_intervalFloat (readonly)

Returns time to wait between retries.

Returns:

  • (Float)

    time to wait between retries



68
69
70
# File 'lib/berkshelf/community_rest.rb', line 68

def retry_interval
  @retry_interval
end

Class Method Details

.unpack(target, destination = Dir.mktmpdir) ⇒ String

Parameters:

  • target (String)

    file path to the tar.gz archive on disk

  • destination (String) (defaults to: Dir.mktmpdir)

    file path to extract the contents of the target to

Returns:



16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/berkshelf/community_rest.rb', line 16

def unpack(target, destination = Dir.mktmpdir)
  if is_gzip_file(target)
    Archive::Tar::Minitar.unpack(Zlib::GzipReader.new(File.open(target, 'rb')), destination)
  elsif is_tar_file(target)
    Archive::Tar::Minitar.unpack(target, destination)
  elsif is_bzip2_file(target)
    Archive::Tar::Minitar.unpack(RBzip2::Decompressor.new(File.open(target, 'rb')), destination)
  else
    raise Berkshelf::UnknownCompressionType.new(target)
  end
  destination
end

.uri_escape_version(version) ⇒ String

Parameters:

Returns:



32
33
34
# File 'lib/berkshelf/community_rest.rb', line 32

def uri_escape_version(version)
  version.to_s.gsub('.', '_')
end

.version_from_uri(uri) ⇒ String

Parameters:

Returns:



39
40
41
# File 'lib/berkshelf/community_rest.rb', line 39

def version_from_uri(uri)
  File.basename(uri.to_s).gsub('_', '.')
end

Instance Method Details

#download(name, version) ⇒ String

Parameters:

Returns:



102
103
104
105
106
107
# File 'lib/berkshelf/community_rest.rb', line 102

def download(name, version)
  archive = stream(find(name, version)[:file])
  self.class.unpack(archive.path)
ensure
  archive.unlink unless archive.nil?
end

#find(name, version) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/berkshelf/community_rest.rb', line 109

def find(name, version)
  response = get("#{name}/versions/#{self.class.uri_escape_version(version)}")

  case response.status
  when (200..299)
    response.body
  when 404
    raise CookbookNotFound, "Cookbook '#{name}' not found at site: '#{api_uri}'"
  else
    raise CommunitySiteError, "Error finding cookbook '#{name}' (#{version}) at site: '#{api_uri}'"
  end
end

#latest_version(name) ⇒ String

Returns the latest version of the cookbook and it’s download link.

Returns:



125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/berkshelf/community_rest.rb', line 125

def latest_version(name)
  response = get(name)

  case response.status
  when (200..299)
    self.class.version_from_uri response.body['latest_version']
  when 404
    raise CookbookNotFound, "Cookbook '#{name}' not found at site: '#{api_uri}'"
  else
    raise CommunitySiteError, "Error retrieving latest version of cookbook '#{name}' at site: '#{api_uri}'"
  end
end

#satisfy(name, constraint) ⇒ String

Parameters:

Returns:



160
161
162
163
164
# File 'lib/berkshelf/community_rest.rb', line 160

def satisfy(name, constraint)
  Solve::Solver.satisfy_best(constraint, versions(name)).to_s
rescue Solve::Errors::NoSolutionError
  nil
end

#stream(target) ⇒ Tempfile

Stream the response body of a remote URL to a file on the local file system

Parameters:

  • target (String)

    a URL to stream the response body from

Returns:

  • (Tempfile)


172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/berkshelf/community_rest.rb', line 172

def stream(target)
  local = Tempfile.new('community-rest-stream')
  local.binmode

  retryable(tries: retries, on: OpenURI::HTTPError, sleep: retry_interval) do
    open(target, 'rb', headers) do |remote|
      local.write(remote.read)
    end
  end

  local
ensure
  local.close(false) unless local.nil?
end

#versions(name) ⇒ Array

Parameters:

Returns:

  • (Array)


141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/berkshelf/community_rest.rb', line 141

def versions(name)
  response = get(name)

  case response.status
  when (200..299)
    response.body['versions'].collect do |version_uri|
      self.class.version_from_uri(version_uri)
    end
  when 404
    raise CookbookNotFound, "Cookbook '#{name}' not found at site: '#{api_uri}'"
  else
    raise CommunitySiteError, "Error retrieving versions of cookbook '#{name}' at site: '#{api_uri}'"
  end
end