Class: PDK::Util::PuppetVersion

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/pdk/util/puppet_version.rb

Constant Summary collapse

PE_VERSIONS_URL =
'https://forgeapi.puppet.com/private/versions/pe'.freeze
DEFAULT_PUPPET_DEV_URL =
'https://github.com/puppetlabs/puppet'.freeze
DEFAULT_PUPPET_DEV_BRANCH =
'main'.freeze

Class Attribute Summary collapse

Instance Method Summary collapse

Class Attribute Details

.instanceObject



15
16
17
# File 'lib/pdk/util/puppet_version.rb', line 15

def instance
  @instance ||= new
end

Instance Method Details

#fetch_puppet_dev(options = {}) ⇒ Object

Raises:



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/pdk/util/puppet_version.rb', line 51

def fetch_puppet_dev(options = {})
  return if options[:run] == :once && puppet_dev_fetched?

  require 'pdk/util/git'

  # Check if the source is cloned and is a readable git repo
  unless PDK::Util::Git.remote_repo? puppet_dev_path
    # Check if the path has something in it already. Delete it and prepare for clone if so.
    if PDK::Util::Filesystem.exist? puppet_dev_path
      PDK::Util::Filesystem.delete(puppet_dev_path) if PDK::Util::Filesystem.file? puppet_dev_path
      PDK::Util::Filesystem.rm_rf(puppet_dev_path) if PDK::Util::Filesystem.directory? puppet_dev_path
    end

    PDK::Util::Filesystem.mkdir_p puppet_dev_path
    clone_result = PDK::Util::Git.git('clone', DEFAULT_PUPPET_DEV_URL, puppet_dev_path)
    return if clone_result[:exit_code].zero?

    PDK.logger.error clone_result[:stdout]
    PDK.logger.error clone_result[:stderr]
    raise PDK::CLI::FatalError, format("Unable to clone git repository from '%{repo}'.", repo: DEFAULT_PUPPET_DEV_URL)
  end

  # Fetch Updates from remote repository
  fetch_result = PDK::Util::Git.git('-C', puppet_dev_path, 'fetch', 'origin')

  unless fetch_result[:exit_code].zero?
    PDK.logger.error fetch_result[:stdout]
    PDK.logger.error fetch_result[:stderr]
    raise PDK::CLI::FatalError, format("Unable to fetch from git remote at '%{repo}'.", repo: DEFAULT_PUPPET_DEV_URL)
  end

  # Reset local repo to latest
  reset_result = PDK::Util::Git.git('-C', puppet_dev_path, 'reset', '--hard', "origin/#{DEFAULT_PUPPET_DEV_BRANCH}")

  @puppet_dev_fetched = true
  return if reset_result[:exit_code].zero?

  PDK.logger.error reset_result[:stdout]
  PDK.logger.error reset_result[:stderr]
  raise PDK::CLI::FatalError, format("Unable to update git repository at '%{cachedir}'.", cachedir: puppet_dev_path)
end

#find_gem_for(version_str) ⇒ Object

Raises:



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
# File 'lib/pdk/util/puppet_version.rb', line 93

def find_gem_for(version_str)
  version = parse_specified_version(version_str)

  # Look for a gem matching exactly the version passed in.
  if version.segments.length == 3
    exact_match_gem = find_gem(Gem::Requirement.create(version))
    return exact_match_gem unless exact_match_gem.nil?
  end

  # Construct a pessimistic version constraint to find the latest
  # available gem matching the level of specificity of version_str.
  requirement_string = version.approximate_recommendation
  requirement_string += '.0' unless version.segments.length == 1
  latest_requirement = Gem::Requirement.create(requirement_string)
  latest_available_gem = find_gem(latest_requirement)

  raise ArgumentError, format('Unable to find a Puppet gem matching %{requirement}.', requirement: latest_requirement) if latest_available_gem.nil?

  # Only issue this warning if they requested an exact version that isn't available.
  if version.segments.length == 3
    PDK.logger.warn(format('Puppet %{requested_version} is not available, activating %{found_version} instead.', requested_version: version_str,
                                                                                                                 found_version: latest_available_gem[:gem_version].version))
  end

  latest_available_gem
end

#from_module_metadata(metadata = nil) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/pdk/util/puppet_version.rb', line 140

def ( = nil)
  require 'pdk/module/metadata'
  require 'pdk/util'

  if .nil?
     = PDK::Util.find_upwards('metadata.json')

    unless 
      PDK.logger.warn 'Unable to determine Puppet version for module: no metadata.json present in module.'
      return
    end

     = PDK::Module::Metadata.from_file()
  end

  .validate_puppet_version_requirement!
   = .puppet_requirement

  # Split combined requirements like ">= 4.7.0 < 6.0.0" into their
  # component requirements [">= 4.7.0", "< 6.0.0"]
  pattern = /#{Gem::Requirement::PATTERN_RAW}/o
  requirement_strings = ['version_requirement'].scan(pattern).map do |req|
    req.compact.join(' ')
  end

  gem_requirement = Gem::Requirement.create(requirement_strings)
  find_gem(gem_requirement)
end

#from_pe_version(version_str) ⇒ Object

Raises:



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/pdk/util/puppet_version.rb', line 120

def from_pe_version(version_str)
  version = parse_specified_version(version_str)

  # Due to the issue with concurrent ruby in older puppet gems
  # we are locking the pe to puppet version mapping to the latest
  # puppet version that is compatible with the pe version.
  safe_versions = {
    2023 => '7.23.0',
    2021 => '7.23.0',
    2019 => '6.29.0'
  }

  gem_version = safe_versions[version.segments[0]]
  raise ArgumentError, format('Unable to map Puppet Enterprise version %{pe_version} to a Puppet version.', pe_version: version_str) if gem_version.nil?

  PDK.logger.info format('Puppet Enterprise %{pe_version} maps to Puppet %{puppet_version}.', pe_version: version_str, puppet_version: gem_version)

  find_gem_for(gem_version)
end

#latest_availableObject

Raises:



39
40
41
42
43
44
45
# File 'lib/pdk/util/puppet_version.rb', line 39

def latest_available
  latest = find_gem(Gem::Requirement.create('>= 0'))

  raise ArgumentError, 'Unable to find a Puppet gem in current Ruby environment or from Rubygems.org.' if latest.nil?

  latest
end

#puppet_dev_envObject



24
25
26
27
28
29
30
31
# File 'lib/pdk/util/puppet_version.rb', line 24

def puppet_dev_env
  require 'pdk/util/ruby_version'

  {
    gem_version: format('file://%{path}', path: puppet_dev_path),
    ruby_version: PDK::Util::RubyVersion.latest_ruby_version
  }
end

#puppet_dev_fetched?Boolean

Returns:



47
48
49
# File 'lib/pdk/util/puppet_version.rb', line 47

def puppet_dev_fetched?
  !@puppet_dev_fetched.nil?
end

#puppet_dev_pathObject



33
34
35
36
37
# File 'lib/pdk/util/puppet_version.rb', line 33

def puppet_dev_path
  require 'pdk/util'

  File.join(PDK::Util.cachedir, 'src', 'puppet')
end