Module: Beaker::ModuleInstallHelper

Includes:
DSL
Defined in:
lib/beaker/module_install_helper.rb

Overview

Provides method for use in module test setup to install the module under test and it’s dependencies on the specified hosts

Instance Method Summary collapse

Instance Method Details

#forge_apiObject



182
183
184
185
186
187
188
189
190
191
# File 'lib/beaker/module_install_helper.rb', line 182

def forge_api
  fa = ENV['BEAKER_FORGE_API']
  unless fa.nil?
    fa = 'https://' + fa if fa !~ /^(https:\/\/|http:\/\/)/i
    fa += '/' unless fa != /\/$/
    return fa
  end

  'https://forgeapi.puppetlabs.com/'
end

#forge_hostObject



171
172
173
174
175
176
177
178
179
180
# File 'lib/beaker/module_install_helper.rb', line 171

def forge_host
  fh = ENV['BEAKER_FORGE_HOST']
  unless fh.nil?
    fh = 'https://' + fh if fh !~ /^(https:\/\/|http:\/\/)/i
    fh += '/' unless fh != /\/$/
    return fh
  end

  'https://forge.puppet.com/'
end

#get_module_source_directory(search_in) ⇒ Object

Use this property to store the module_source_dir, so we don’t traverse the tree every time



156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/beaker/module_install_helper.rb', line 156

def get_module_source_directory(search_in)
  module_source_dir = nil
  # here we go up the file tree and search the directories for a
  # valid metadata.json
  while module_source_dir.nil? && search_in != File.dirname(search_in)
    # remove last segment (file or folder, doesn't matter)
    search_in = File.dirname(search_in)

    # Append metadata.json, check it exists in the directory we're searching
     = File.join(search_in, 'metadata.json')
    module_source_dir = search_in if File.exist?()
  end
  module_source_dir
end

#hosts_to_install_module_onObject

This method will return array of all masters. If no masters exist, it will return all agent nodes. If no nodes tagged master or agent exist, all nodes will be returned



126
127
128
129
130
131
132
133
134
# File 'lib/beaker/module_install_helper.rb', line 126

def hosts_to_install_module_on
  masters = hosts_with_role(hosts, :master)
  return masters unless masters.empty?

  agents = hosts_with_role(hosts, :agent)
  return agents unless agents.empty?

  hosts
end

#install_moduleObject

This method calls the install_module_on method for each host which is a master, or if no master is present, on all agent nodes.



10
11
12
# File 'lib/beaker/module_install_helper.rb', line 10

def install_module
  install_module_on hosts_to_install_module_on
end

#install_module_dependencies(deps = nil) ⇒ Object

This method calls the install_module_dependencies_on method for each host which is a master, or if no master is present, on all agent nodes.



24
25
26
# File 'lib/beaker/module_install_helper.rb', line 24

def install_module_dependencies(deps = nil)
  install_module_dependencies_on(hosts_to_install_module_on, deps)
end

#install_module_dependencies_on(hsts, deps = nil) ⇒ Object

This method will install the module under tests module dependencies on the specified host(s) from the dependencies list in metadata.json



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/beaker/module_install_helper.rb', line 30

def install_module_dependencies_on(hsts, deps = nil)
  hsts = [hsts] if hsts.is_a?(Hash)
  deps = deps.nil? ?  : deps

  fh = ENV['BEAKER_FORGE_HOST']

  hsts.each do |host|
    deps.each do |dep|
      if fh.nil?
        install_puppet_module_via_pmt_on(host, dep)
      else
        with_forge_stubbed_on(host) do
          install_puppet_module_via_pmt_on(host, dep)
        end
      end
    end
  end
end

#install_module_from_forge(mod_name, ver_req) ⇒ Object



49
50
51
# File 'lib/beaker/module_install_helper.rb', line 49

def install_module_from_forge(mod_name, ver_req)
  install_module_from_forge_on(hosts_to_install_module_on, mod_name, ver_req)
end

#install_module_from_forge_on(hsts, mod_name, ver_req) ⇒ Object



53
54
55
56
57
58
59
60
61
# File 'lib/beaker/module_install_helper.rb', line 53

def install_module_from_forge_on(hsts, mod_name, ver_req)
  mod_name.sub!('/', '-')
  dependency = {
    module_name: mod_name,
    version: module_version_from_requirement(mod_name, ver_req)
  }

  install_module_dependencies_on(hsts, [dependency])
end

#install_module_on(host) ⇒ Object

This method will install the module under test on the specified host(s) from the source on the local machine



16
17
18
19
20
# File 'lib/beaker/module_install_helper.rb', line 16

def install_module_on(host)
  copy_module_to(host,
                 source:      $module_source_dir,
                 module_name: )
end

#module_dependencies_from_metadataObject

This method returns an array of dependencies from the metadata.json file in the format of an array of hashes, containing :module_name and optionally :version elements. If no dependencies are specified, empty array is returned



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/beaker/module_install_helper.rb', line 66

def 
   = 
  return [] unless .key?('dependencies')

  dependencies = []
  ['dependencies'].each do |d|
    tmp = { module_name: d['name'].sub!('/', '-') }

    if d.key?('version_requirement')
      tmp[:version] = module_version_from_requirement(tmp[:module_name],
                                                      d['version_requirement'])
    end
    dependencies.push(tmp)
  end

  dependencies
end

#module_metadataObject

This method uses the module_source_directory path to read the metadata.json file into a json array



146
147
148
149
150
151
152
# File 'lib/beaker/module_install_helper.rb', line 146

def 
   = "#{$module_source_dir}/metadata.json"
  unless File.exist?()
    raise "Error loading metadata.json file from #{$module_source_dir}"
  end
  JSON.parse(File.read())
end

#module_name_from_metadataObject

This method will read the ‘name’ attribute from metadata.json file and remove the first segment. E.g. puppetlabs-vcsrepo -> vcsrepo



138
139
140
141
142
# File 'lib/beaker/module_install_helper.rb', line 138

def 
  res = get_module_name ['name']
  raise 'Error getting module name' unless res
  res[1]
end

#module_version_from_requirement(mod_name, vr_str) ⇒ Object

This method takes a module name and the version requirement string from the metadata.json file, containing either lower bounds of version or both lower and upper bounds. The function then uses the forge rest endpoint to find the most recent release of the given module matching the version requirement



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/beaker/module_install_helper.rb', line 88

def module_version_from_requirement(mod_name, vr_str)
  uri = URI("#{forge_api}v3/modules/#{mod_name}")
  response = Net::HTTP.get(uri)
  forge_data = JSON.parse(response)

  vrs = version_requirements_from_string(vr_str)

  # Here we iterate the releases of the given module and pick the most recent
  # that matches to version requirement
  forge_data['releases'].each do |rel|
    return rel['version'] if vrs.all? { |vr| vr.match?('', rel['version']) }
  end

  raise "No release version found matching '#{vr_str}'"
end

#version_requirements_from_string(vr_str) ⇒ Object

This method takes a version requirement string as specified in the link below, with either simply a lower bound, or both lower and upper bounds and returns an array of Gem::Dependency objects docs.puppet.com/puppet/latest/modules_metadata.html



108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/beaker/module_install_helper.rb', line 108

def version_requirements_from_string(vr_str)
  ops = vr_str.scan(/[(<|>|=)]{1,2}/i)
  vers = vr_str.scan(/[(0-9|\.)]+/i)

  raise 'Invalid version requirements' if ops.count != 0 &&
                                          ops.count != vers.count

  vrs = []
  ops.each_with_index do |op, index|
    vrs.push(Gem::Dependency.new('', "#{op} #{vers[index]}"))
  end

  vrs
end