Class: PuppetForge::V3::Release

Inherits:
Base
  • Object
show all
Defined in:
lib/puppet_forge/v3/release.rb

Overview

Models a specific release version of a Puppet Module on the Forge.

Defined Under Namespace

Classes: ChecksumMismatch

Constant Summary

Constants inherited from Base

Base::API_VERSION

Constants included from Connection

Connection::AUTHORIZATION_TOKEN_REGEX, Connection::USER_AGENT

Instance Attribute Summary

Attributes included from Connection

#conn

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

all, all_stateless, api_version, #attribute, #attributes, convert_plus_to_space, find, find_request, find_stateless, get_collection, get_collection_request, get_collection_stateless, #has_attribute?, #initialize, lru_cache, lru_cache_key, new_collection, #orm_resp_item, request, split_uri_path, where, where_request, where_stateless

Methods included from Connection

accept_language, accept_language=, authorization, authorization=, default_connection, make_connection, proxy, proxy=

Methods included from LazyRelations

included, #lazy, #lazy_collection, #name, #parent

Methods included from LazyAccessors

#class_name, #fetch, included, #inspect, #method_missing

Constructor Details

This class inherits a constructor from PuppetForge::V3::Base

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class PuppetForge::LazyAccessors

Class Method Details

.upload(path) ⇒ Object

Uploads the tarbarll to the forge

Parameters:

  • path (Pathname)

    tarball file path

Returns:

  • resp



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/puppet_forge/v3/release.rb', line 46

def self.upload(path)
  # We want to make sure that the file exists before trying to upload it
  raise PuppetForge::FileNotFound, "The file '#{path}' does not exist." unless File.file?(path)

  file = File.open(path, 'rb')
  encoded_string = Base64.encode64(file.read)
  data = { file: encoded_string }

  resp = conn.post do |req|
    req.url '/v3/releases'
    req.headers['Content-Type'] = 'application/json'
    req.body = data.to_json
  end

  [self, resp]
rescue Faraday::ClientError => e
  if e.response
    case e.response[:status]
    when 403
      raise PuppetForge::ReleaseForbidden.from_response(e.response)
    when 400
      raise PuppetForge::ReleaseBadContent.from_response(e.response)
    end
  end

  raise e
end

Instance Method Details

#download(path) ⇒ void

This method returns an undefined value.

Downloads the Release tarball to the specified file path.

Parameters:

  • path (Pathname)


29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/puppet_forge/v3/release.rb', line 29

def download(path)
  resp = self.class.conn.get(download_url)
  path.open('wb') { |fh| fh.write(resp.body) }
rescue Faraday::ResourceNotFound => e
  raise PuppetForge::ReleaseNotFound, "The module release #{slug} does not exist on #{self.class.conn.url_prefix}.", e.backtrace
rescue Faraday::ClientError => e
  if e.response && e.response[:status] == 403
    raise PuppetForge::ReleaseForbidden.from_response(e.response)
  else
    raise e
  end
end

#download_urlString

Returns a fully qualified URL for downloading this release from the Forge.

Returns:

  • (String)

    fully qualified download URL for release



17
18
19
20
21
22
23
# File 'lib/puppet_forge/v3/release.rb', line 17

def download_url
  if URI.parse(file_uri).host.nil?
    URI.join(PuppetForge.host, file_uri[1..-1]).to_s
  else
    file_uri
  end
end

#verify(path, allow_md5 = true) ⇒ void

This method returns an undefined value.

Verify that a downloaded module matches the best available checksum in the metadata for this release, validates SHA-256 checksum if available, otherwise validates MD5 checksum

Parameters:

  • path (Pathname)

Raises:



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/puppet_forge/v3/release.rb', line 79

def verify(path, allow_md5 = true)
  checksum =
    if self.respond_to?(:file_sha256) && !self.file_sha256.nil? && !self.file_sha256.size.zero?
      {
        type: "SHA-256",
        expected: self.file_sha256,
        actual: Digest::SHA256.file(path).hexdigest,
      }
    elsif allow_md5
      {
        type: "MD5",
        expected: self.file_md5,
        actual: Digest::MD5.file(path).hexdigest,
      }
    else
      raise PuppetForge::Error.new("Cannot verify module release: SHA-256 checksum is not available in API response and fallback to MD5 has been forbidden.")
    end

  return if checksum[:expected] == checksum[:actual]

  raise ChecksumMismatch.new("Unable to validate #{checksum[:type]} checksum for #{path}, download may be corrupt!")
end