Class: Librarian::Puppet::Source::Forge::Repo

Inherits:
Repo
  • Object
show all
Includes:
Util
Defined in:
lib/librarian/puppet/source/forge/repo.rb

Direct Known Subclasses

RepoV1, RepoV3

Instance Attribute Summary

Attributes inherited from Repo

#name, #source

Instance Method Summary collapse

Methods included from Util

#clean_uri, #cp_r, #debug, #info, #module_name, #normalize_name, #rsync?, #warn

Methods inherited from Repo

#cache_path, #environment, #initialize, #vendored?, #vendored_path, #version_unpacked_cache_path

Constructor Details

This class inherits a constructor from Librarian::Puppet::Source::Repo

Instance Method Details

#cache_version_unpacked!(version) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/librarian/puppet/source/forge/repo.rb', line 72

def cache_version_unpacked!(version)
  path = version_unpacked_cache_path(version)
  return if path.directory?

  # The puppet module command is only available from puppet versions >= 2.7.13
  #
  # Specifying the version in the gemspec would force people to upgrade puppet while it's still usable for git
  # So we do some more clever checking
  #
  # Executing older versions or via puppet-module tool gives an exit status = 0 .
  #
  check_puppet_module_options

  path.mkpath

  target = vendored?(name, version) ? vendored_path(name, version).to_s : name

  # can't pass the default v3 forge url (http://forgeapi.puppetlabs.com)
  # to clients that use the v1 API (https://forge.puppet.com)
  # nor the other way around
  module_repository = source.uri.to_s

  if Forge.client_api_version() > 1 and module_repository =~ %r{^http(s)?://forge\.puppetlabs\.com}
    module_repository = "https://forgeapi.puppetlabs.com"
    warn { "Replacing Puppet Forge API URL to use v3 #{module_repository} as required by your client version #{Librarian::Puppet.puppet_version}" }
  end

  m = module_repository.match(%r{^http(s)?://forge(api)?\.puppetlabs\.com})
  if Forge.client_api_version() == 1 and m
    ssl = m[1]
    # Puppet 2.7 can't handle the 302 returned by the https url, so stick to http
    if ssl and Librarian::Puppet::puppet_gem_version < Gem::Version.create('3.0.0')
      warn { "Using plain http as your version of Puppet #{Librarian::Puppet::puppet_gem_version} can't download from forge.puppetlabs.com using https" }
      ssl = nil
    end
    module_repository = "http#{ssl}://forge.puppetlabs.com"
  end

  command = %W{puppet module install --version #{version} --target-dir}
  command.push(*[path.to_s, "--module_repository", module_repository, "--modulepath", path.to_s, "--module_working_dir", path.to_s, "--ignore-dependencies", target])
  debug { "Executing puppet module install for #{name} #{version}: #{command.join(" ").gsub(module_repository, source.to_s)}" }

  begin
    Librarian::Posix.run!(command)
  rescue Posix::CommandFailure => e
    # Rollback the directory if the puppet module had an error
    begin
      path.unlink
    rescue => u
      debug("Unable to rollback path #{path}: #{u}")
    end
    tar = Dir[File.join(path.to_s, "**/*.tar.gz")]
    msg = ""
    if e.message =~ /Unexpected EOF in archive/ and !tar.empty?
      file = tar.first
      msg = " (looks like an incomplete download of #{file})"
    end
    raise Error, "Error executing puppet module install#{msg}. Check that this command succeeds:\n#{command.join(" ")}\nError:\n#{e.message}"
  end

end

#check_puppet_module_optionsObject



134
135
136
137
138
139
140
# File 'lib/librarian/puppet/source/forge/repo.rb', line 134

def check_puppet_module_options
  min_version    = Gem::Version.create('2.7.13')

  if Librarian::Puppet.puppet_gem_version < min_version
    raise Error, "To get modules from the forge, we use the puppet faces module command. For this you need at least puppet version 2.7.13 and you have #{Librarian::Puppet.puppet_version}"
  end
end

#dependencies(version) ⇒ Object

return map with dependencies in the form => version,… version: Librarian::Manifest::Version



31
32
33
# File 'lib/librarian/puppet/source/forge/repo.rb', line 31

def dependencies(version)
  # implement in subclasses
end

#get_versionsObject

fetch list of versions ordered for newer to older



25
26
27
# File 'lib/librarian/puppet/source/forge/repo.rb', line 25

def get_versions
  # implement in subclasses
end

#install_version!(version, install_path) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/librarian/puppet/source/forge/repo.rb', line 47

def install_version!(version, install_path)
  if environment.local? && !vendored?(name, version)
    raise Error, "Could not find a local copy of #{name} at #{version}."
  end

  if environment.vendor?
    vendor_cache(name, version) unless vendored?(name, version)
  end

  cache_version_unpacked! version

  if install_path.exist? && rsync? != true
    install_path.rmtree
  end

  unpacked_path = version_unpacked_cache_path(version).join(module_name(name))

  unless unpacked_path.exist?
    raise Error, "#{unpacked_path} does not exist, something went wrong. Try removing it manually"
  else
    cp_r(unpacked_path, install_path)
  end

end

#manifestsObject



41
42
43
44
45
# File 'lib/librarian/puppet/source/forge/repo.rb', line 41

def manifests
  versions.map do |version|
    Manifest.new(source, name, version)
  end
end

#url(name, version) ⇒ Object

return the url for a specific version tarball version: Librarian::Manifest::Version



37
38
39
# File 'lib/librarian/puppet/source/forge/repo.rb', line 37

def url(name, version)
  # implement in subclasses
end

#vendor_cache(name, version) ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
# File 'lib/librarian/puppet/source/forge/repo.rb', line 142

def vendor_cache(name, version)
  url = url(name, version)
  path = vendored_path(name, version).to_s
  debug { "Downloading #{url} into #{path}"}
  environment.vendor!
  File.open(path, 'wb') do |f|
    URI.open(url, 'rb') do |input|
      f.write(input.read)
    end
  end
end

#versionsObject



13
14
15
16
17
18
19
20
21
22
# File 'lib/librarian/puppet/source/forge/repo.rb', line 13

def versions
  return @versions if @versions
  @versions = get_versions
  if @versions.empty?
    info { "No versions found for module #{name}" }
  else
    debug { "  Module #{name} found versions: #{@versions.join(", ")}" }
  end
  @versions
end