Class: Berkshelf::API::SiteConnector::Opscode

Inherits:
Object
  • Object
show all
Includes:
Logging, Celluloid
Defined in:
lib/berkshelf/api/site_connector/opscode.rb

Constant Summary collapse

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

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Logging

init, #logger

Constructor Details

#initialize(options = {}) ⇒ Opscode

Returns a new instance of Opscode.

Parameters:

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

    a customizable set of options

Options Hash (options):

  • :url (String) — default: {V1_API}

    url of community site

  • :retries (Integer) — default: 5

    how many download retry attempts to make

  • :retry_interval (Float) — default: 0.5

    how long to wait before retrying again



45
46
47
48
49
50
51
52
53
# File 'lib/berkshelf/api/site_connector/opscode.rb', line 45

def initialize(options = {})
  options  = { url: V1_API, retries: 5, retry_interval: 0.5 }.merge(options)
  @api_uri = options[:url]

  @connection = Faraday.new(@api_uri) do |c|
    c.response :parse_json
    c.use Faraday::Adapter::NetHttp
  end
end

Instance Attribute Details

#api_uriString (readonly)

Returns:

  • (String)


31
32
33
# File 'lib/berkshelf/api/site_connector/opscode.rb', line 31

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



34
35
36
# File 'lib/berkshelf/api/site_connector/opscode.rb', line 34

def retries
  @retries
end

#retry_intervalFloat (readonly)

Returns time to wait between retries.

Returns:

  • (Float)

    time to wait between retries



37
38
39
# File 'lib/berkshelf/api/site_connector/opscode.rb', line 37

def retry_interval
  @retry_interval
end

Class Method Details

.uri_escape_version(version) ⇒ String

Parameters:

  • version (String)

Returns:

  • (String)


13
14
15
# File 'lib/berkshelf/api/site_connector/opscode.rb', line 13

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

.version_from_uri(uri) ⇒ String

Parameters:

  • uri (String)

Returns:

  • (String)


20
21
22
# File 'lib/berkshelf/api/site_connector/opscode.rb', line 20

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

Instance Method Details

#cookbooksArray<String>

Returns A list of cookbook names available on the server.

Returns:

  • (Array<String>)

    A list of cookbook names available on the server



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/berkshelf/api/site_connector/opscode.rb', line 57

def cookbooks
  start     = 0
  count     = connection.get("cookbooks").body["total"]
  cookbooks = Array.new

  while count > 0
    req = connection.get("cookbooks?start=#{start}&items=#{count}")
    chunk = req.body["items"]
    if chunk
      cookbooks += chunk
      start += 100
      count -= 100
    else
      log.warn "Didn't get any cookbooks - #{req.body}"
    end
  end

  cookbooks.map { |cb| cb["cookbook_name"] }
end

#download(name, version, destination = Dir.mktmpdir) ⇒ String?

Download the cookbook with the given name and version to the destination. The directory containing the extracted contents will be returned on success. On failure, nil will be returned.

Parameters:

  • cookbook (String)

    The name of the cookbook to download

  • version (String)

    The version of the cookbook to download

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

    The directory to download the cookbook to

Returns:

  • (String, nil)


107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/berkshelf/api/site_connector/opscode.rb', line 107

def download(name, version, destination = Dir.mktmpdir)
  log.debug "Downloading #{name}(#{version})"
  if uri = download_uri(name, version)
    begin
      archive = stream(uri)
      Archive.extract(archive.path, destination)
      destination
    rescue => ex
      log.warn "Error downloading/extracting #{name} (#{version}): #{ex}"
      nil
    ensure
      archive.unlink unless archive.nil?
    end
  end
end

#download_uri(name, version) ⇒ String?

Return the location where a cookbook of the given name and version can be downloaded from

Parameters:

  • cookbook (String)

    The name of the cookbook

  • version (String)

    The version of the cookbook

Returns:

  • (String, nil)


131
132
133
134
135
136
# File 'lib/berkshelf/api/site_connector/opscode.rb', line 131

def download_uri(name, version)
  unless cookbook = find(name, version)
    return nil
  end
  cookbook[:file]
end

#find(name, version) ⇒ Hashie::Mash?

Parameters:

  • cookbook (String)

    The name of the cookbook to retrieve

  • version (String)

    The version of the cookbook to retrieve

Returns:

  • (Hashie::Mash, nil)


144
145
146
147
148
149
150
151
152
153
# File 'lib/berkshelf/api/site_connector/opscode.rb', line 144

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

  case response.status
  when (200..299)
    response.body
  else
    nil
  end
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)


161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/berkshelf/api/site_connector/opscode.rb', line 161

def stream(target)
  local = Tempfile.new('opscode-site-stream')
  local.binmode

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

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

#versions(cookbook) ⇒ Array<String>

Returns A list of versions of this cookbook available on the server.

Parameters:

  • cookbook (String)

    the name of the cookbook to find version for

Returns:

  • (Array<String>)

    A list of versions of this cookbook available on the server



82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/berkshelf/api/site_connector/opscode.rb', line 82

def versions(cookbook)
  response = connection.get("cookbooks/#{cookbook}")

  case response.status
  when (200..299)
    response.body['versions'].collect do |version_uri|
      self.class.version_from_uri(version_uri)
    end
  else
    Array.new
  end
end