puppet-moddeps 0.3.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/.github/dependabot.yml +12 -0
- data/.github/workflows/gempush.yml +29 -0
- data/.github/workflows/ruby.yaml +35 -0
- data/.gitignore +26 -24
- data/.rspec +2 -0
- data/.travis.yml +12 -30
- data/.yardopts +3 -0
- data/CHANGELOG.md +30 -0
- data/Gemfile +4 -4
- data/Guardfile +22 -15
- data/LICENSE +200 -27
- data/README.md +75 -71
- data/Rakefile +14 -11
- data/Vagrantfile +16 -16
- data/bin/puppet-moddeps +6 -5
- data/lib/puppet/moddeps.rb +8 -73
- data/lib/puppet/moddeps/installer.rb +244 -0
- data/lib/puppet/moddeps/module.rb +87 -0
- data/lib/puppet/moddeps/version.rb +5 -5
- data/puppet-moddeps.gemspec +50 -41
- data/spec/puppet/moddeps/installer_spec.rb +122 -0
- data/spec/spec_helper.rb +13 -8
- metadata +159 -77
- data/.coveralls.yml +0 -2
- data/Gemfile.lock +0 -107
- data/scripts/pretest.sh +0 -20
- data/scripts/vagrant-user.sh +0 -21
- data/spec/moddeps_spec.rb +0 -56
data/README.md
CHANGED
@@ -1,71 +1,75 @@
|
|
1
|
-
# Puppet::Moddeps
|
2
|
-
|
3
|
-
[![Gem
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
3. Install
|
49
|
-
4.
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
1
|
+
# Puppet::Moddeps
|
2
|
+
|
3
|
+
[![Gem](https://img.shields.io/gem/v/puppet-moddeps)](https://rubygems.org/gems/puppet-moddeps)
|
4
|
+
[![Actions Status](https://github.com/genebean/puppet-moddeps/workflows/Rspec%20Tests/badge.svg)](https://github.com/genebean/puppet-moddeps/actions)
|
5
|
+
[![codecov](https://codecov.io/gh/genebean/puppet-moddeps/branch/master/graph/badge.svg?token=9sn4KbY0yu)](https://app.codecov.io/gh/genebean/puppet-moddeps)
|
6
|
+
![GitHub](https://img.shields.io/github/license/genebean/puppet-moddeps)
|
7
|
+
|
8
|
+
## Description
|
9
|
+
|
10
|
+
This gem will allow you to pull in all missing dependencies for a given Puppet module by running `puppet-moddeps some_module`. This is targeted specifically at private modules or modules cloned from GitHub that have a populated `metadata.json` file. It really shines as a tool to install all the dependencies of a module that you have just created or when you have just updated the list of dependencies in a module's `metadata.json` file.
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
puppet-moddeps has been extensively tested using the ruby bundled with the Puppet agent. The recommended way to use this gem is to first install puppet and then open an elevated command prompt and run this:
|
15
|
+
|
16
|
+
```bash
|
17
|
+
puppet resource package puppet-moddeps provider=puppet_gem ensure=latest
|
18
|
+
```
|
19
|
+
|
20
|
+
Alternatively, you can also install it using another instance of Ruby so long as it is at least version 2.5.7.
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
After installation, you can run `puppet-moddeps some_module`, replacing `some_module` with the name of any module installed in `/etc/puppetlabs/code/environments/production/modules/`. It will resolve the module's dependencies based on its `metadata.json` file and install each of them.
|
25
|
+
|
26
|
+
### Using in a module's Vagrantfile
|
27
|
+
|
28
|
+
If your module includes a [`Vagrantfile`](https://www.vagrantup.com/docs/vagrantfile) you can utilize this gem as part of your provisioning step by adding this to it:
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
MODULE_NAME='some_module'
|
32
|
+
Vagrant.configure('2') do |config|
|
33
|
+
config.vm.box = 'genebean/centos-7-puppet-latest' # Any box that includes Puppet will work here
|
34
|
+
config.vm.provision 'shell', inline: <<-SCRIPT
|
35
|
+
puppet resource file /etc/puppetlabs/code/environments/production/modules/#{MODULE_NAME} ensure=link target=/vagrant force=true
|
36
|
+
/opt/puppetlabs/puppet/bin/gem install puppet-moddeps
|
37
|
+
/opt/puppetlabs/puppet/bin/puppet-moddeps #{MODULE_NAME}
|
38
|
+
SCRIPT
|
39
|
+
end
|
40
|
+
```
|
41
|
+
|
42
|
+
## Contributing
|
43
|
+
|
44
|
+
Pull requests are welcome!
|
45
|
+
|
46
|
+
1. Fork it ( https://github.com/genebean/puppet-moddeps/fork )
|
47
|
+
2. Create a feature branch
|
48
|
+
3. Install bundler (`gem install bundler`)
|
49
|
+
4. Install development gems (`bundle install`)
|
50
|
+
5. Open a second terminal and use guard to make sure your code doesn't break anything (`bundle exec guard -p`)
|
51
|
+
6. Commit your changes and associated tests (`git commit -am 'Add some feature'`)
|
52
|
+
7. Push to the branch (`git push origin my-new-feature`)
|
53
|
+
8. Create a new pull request
|
54
|
+
|
55
|
+
### Vagrant
|
56
|
+
|
57
|
+
Development and testing can also be done utilizing the included `Vagrantfile`.
|
58
|
+
To do so, install [Vagrant][vagrant] and [VirtualBox][vbox], fork and clone the
|
59
|
+
project, cd into the project, and run `vagrant up` followed by `vagrant ssh`.
|
60
|
+
The setup process will take care of running `bundle install` for you. You
|
61
|
+
can find the code symlinked into the vagrant user's home directory. Also, RVM
|
62
|
+
is installed system-wide in the referenced Vagrant box.
|
63
|
+
|
64
|
+
### Tests
|
65
|
+
|
66
|
+
Please try and write tests using Rspec's expect syntax for any code you add or change.
|
67
|
+
Code must have tests before it will be merged.
|
68
|
+
|
69
|
+
## License
|
70
|
+
|
71
|
+
This code is released under the Apache 2.0 license. A copy is in the LICENSE file in this repo.
|
72
|
+
|
73
|
+
[rvm]: http://rvm.io
|
74
|
+
[vbox]: https://www.virtualbox.org
|
75
|
+
[vagrant]: https://www.vagrantup.com
|
data/Rakefile
CHANGED
@@ -1,11 +1,14 @@
|
|
1
|
-
require 'bundler/gem_tasks'
|
2
|
-
require 'rspec/core/rake_task'
|
3
|
-
|
4
|
-
|
5
|
-
#
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
require 'yard'
|
4
|
+
|
5
|
+
# Default directory to look in is `/specs`
|
6
|
+
# Run with `rake spec`
|
7
|
+
RSpec::Core::RakeTask.new(:spec) do |task|
|
8
|
+
task.rspec_opts = ['--color', '--format', 'documentation']
|
9
|
+
end
|
10
|
+
|
11
|
+
YARD::Rake::YardocTask.new
|
12
|
+
|
13
|
+
task :default => :spec
|
14
|
+
|
data/Vagrantfile
CHANGED
@@ -1,16 +1,16 @@
|
|
1
|
-
# -*- mode: ruby -*-
|
2
|
-
# vi: set ft=ruby :
|
3
|
-
|
4
|
-
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
|
5
|
-
VAGRANTFILE_API_VERSION = "2"
|
6
|
-
|
7
|
-
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
8
|
-
config.vm.box = "genebean/
|
9
|
-
|
10
|
-
config.vm.
|
11
|
-
|
12
|
-
config.vm.
|
13
|
-
|
14
|
-
config.vm.provision "shell", inline: "
|
15
|
-
config.vm.provision "shell",
|
16
|
-
end
|
1
|
+
# -*- mode: ruby -*-
|
2
|
+
# vi: set ft=ruby :
|
3
|
+
|
4
|
+
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
|
5
|
+
VAGRANTFILE_API_VERSION = "2"
|
6
|
+
|
7
|
+
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
8
|
+
config.vm.box = "genebean/centos-7-rvm-multi"
|
9
|
+
|
10
|
+
config.vm.network "forwarded_port", guest: 8808, host: 8808 # used for Yard docs
|
11
|
+
|
12
|
+
config.vm.synced_folder "./", "/home/vagrant/puppet-moddeps"
|
13
|
+
|
14
|
+
config.vm.provision "shell", inline: "yum -y install dos2unix git nano ruby-devel tree vim-enhanced"
|
15
|
+
config.vm.provision "shell", inline: "echo 'install bundler after selecting a ruby with RVM'"
|
16
|
+
end
|
data/bin/puppet-moddeps
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'puppet/moddeps'
|
4
|
-
|
5
|
-
Puppet::Moddeps.
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'puppet/moddeps'
|
4
|
+
|
5
|
+
depinstaller = Puppet::Moddeps::Installer.new
|
6
|
+
depinstaller.install(ARGV)
|
data/lib/puppet/moddeps.rb
CHANGED
@@ -1,73 +1,8 @@
|
|
1
|
-
require 'puppet/moddeps/
|
2
|
-
require '
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
@@default_module_path = '/etc/puppet/modules'
|
10
|
-
|
11
|
-
def Moddeps.installDeps(*puppet_module)
|
12
|
-
|
13
|
-
if ( puppet_module.size >=1 and puppet_module[0].is_a?(Array) )
|
14
|
-
args = puppet_module[0]
|
15
|
-
else
|
16
|
-
args = puppet_module
|
17
|
-
end
|
18
|
-
|
19
|
-
if ( args.size == 1 )
|
20
|
-
if Moddeps.checkIfInstalled(args[0])
|
21
|
-
Moddeps.parseMetadata(args[0])
|
22
|
-
Moddeps.installModules
|
23
|
-
else
|
24
|
-
puts "Can't find #{args[0]} in #{@@default_module_path}"
|
25
|
-
end
|
26
|
-
else
|
27
|
-
Moddeps.help
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def Moddeps.help
|
32
|
-
puts 'Usage: puppet-moddeps module'
|
33
|
-
puts ' Call puppet-moddeps with the name of one installed module'
|
34
|
-
end
|
35
|
-
|
36
|
-
def Moddeps.checkIfInstalled(file)
|
37
|
-
File.directory?("#{@@default_module_path}/#{file}")
|
38
|
-
end
|
39
|
-
|
40
|
-
def Moddeps.parseMetadata(puppet_module)
|
41
|
-
metadata = File.read("#{@@default_module_path}/#{puppet_module}/metadata.json")
|
42
|
-
data = JSON.parse(metadata)
|
43
|
-
@deps = Moddeps.getDeps(data)
|
44
|
-
end
|
45
|
-
|
46
|
-
def Moddeps.getDeps(data)
|
47
|
-
dependencies = []
|
48
|
-
data['dependencies'].each do |dep|
|
49
|
-
depname = dep["name"].sub '/', '-'
|
50
|
-
dependencies.push( depname )
|
51
|
-
end
|
52
|
-
|
53
|
-
return dependencies
|
54
|
-
end
|
55
|
-
|
56
|
-
def Moddeps.installModules
|
57
|
-
if @deps.size > 0
|
58
|
-
@deps.each do |dep|
|
59
|
-
if Moddeps.checkIfInstalled(dep)
|
60
|
-
puts "#{dep} is already installed, skipping."
|
61
|
-
else
|
62
|
-
cmd = "/usr/bin/puppet module install #{dep}"
|
63
|
-
puts "Running \"#{cmd}\"..."
|
64
|
-
%x(#{cmd})
|
65
|
-
end
|
66
|
-
end
|
67
|
-
else
|
68
|
-
puts 'No dependencies were marked for installation.'
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
end
|
73
|
-
end
|
1
|
+
require 'puppet/moddeps/installer'
|
2
|
+
require 'puppet/moddeps/version'
|
3
|
+
|
4
|
+
module Puppet
|
5
|
+
module Moddeps
|
6
|
+
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,244 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'puppetfile-resolver'
|
3
|
+
require 'puppet/moddeps/module'
|
4
|
+
|
5
|
+
module Puppet
|
6
|
+
module Moddeps
|
7
|
+
class Installer
|
8
|
+
|
9
|
+
# The path to which modules will be installed
|
10
|
+
#
|
11
|
+
# @return [String]
|
12
|
+
# The path to which modules will be installed
|
13
|
+
attr_reader :module_path
|
14
|
+
|
15
|
+
# The version of Puppet that will be used when resolving dependencies.
|
16
|
+
# If none is provided then a Puppet version constraint is not applied
|
17
|
+
# during resolution.
|
18
|
+
#
|
19
|
+
# @return [String]
|
20
|
+
# The version of Puppet that will be used when resolving dependencies
|
21
|
+
# if one was specified.
|
22
|
+
attr_reader :puppet_version
|
23
|
+
|
24
|
+
# Creates an instance of Puppet::Moddeps::Installer
|
25
|
+
#
|
26
|
+
# @param module_path [String]
|
27
|
+
# The path to which modules will be installed
|
28
|
+
# @param puppet_version [String]
|
29
|
+
# The verion of Puppet to use when resolving dependencies
|
30
|
+
#
|
31
|
+
# @example No parameters
|
32
|
+
# depinstaller = Puppet::Moddeps::Installer.new
|
33
|
+
#
|
34
|
+
# @example Specify a module path
|
35
|
+
# depinstaller = Puppet::Moddeps::Installer.new('/tmp')
|
36
|
+
#
|
37
|
+
# @example Specify a module path and a Puppet version
|
38
|
+
# depinstaller = Puppet::Moddeps::Installer.new('/tmp', '6.18.0')
|
39
|
+
#
|
40
|
+
def initialize(module_path=nil, puppet_version=nil)
|
41
|
+
if module_path
|
42
|
+
abort('The provided module path was not a string.') unless module_path.is_a?(String)
|
43
|
+
@module_path = module_path
|
44
|
+
else
|
45
|
+
separator = self.path_separator(RbConfig::CONFIG['host_os'])
|
46
|
+
@module_path = %x(puppet config print modulepath).split(separator)[0].strip
|
47
|
+
end
|
48
|
+
|
49
|
+
if puppet_version
|
50
|
+
abort('The provided puppet version was not a string.') unless puppet_version.is_a?(String)
|
51
|
+
end
|
52
|
+
|
53
|
+
@puppet_version = puppet_version
|
54
|
+
|
55
|
+
@usage = <<~ENDUSAGE
|
56
|
+
Usage: puppet-moddeps module_one [module_two] [...]
|
57
|
+
Call puppet-moddeps with the name of one or more installed modules'
|
58
|
+
ENDUSAGE
|
59
|
+
end
|
60
|
+
|
61
|
+
# Installs the dependencies for one or more local modules. This is the
|
62
|
+
# primary entry point for this class.
|
63
|
+
#
|
64
|
+
# @param puppet_module [Array[String]]
|
65
|
+
# An array of strings representig the names of one or more locally
|
66
|
+
# installed puppet modules.
|
67
|
+
#
|
68
|
+
# @example Install dependencies for one module
|
69
|
+
# depinstaller.install(['apache'])
|
70
|
+
#
|
71
|
+
# @example Install dependencies for multiple module
|
72
|
+
# depinstaller.install(['apache', 'nginx'])
|
73
|
+
def install(*puppet_module)
|
74
|
+
# puppet_module will always be an array.
|
75
|
+
# The elements of the array are the values passed in.
|
76
|
+
if puppet_module.nil? || puppet_module.size == 0 || puppet_module[0].nil? || puppet_module[0].size == 0
|
77
|
+
puts 'input problem'
|
78
|
+
abort(@usage)
|
79
|
+
end
|
80
|
+
|
81
|
+
module_array = puppet_module[0]
|
82
|
+
|
83
|
+
# The intent is to only accept strings as arguments.
|
84
|
+
# It is also expected that all arguments are installed modules
|
85
|
+
module_array.each do |mod|
|
86
|
+
abort(@usage) unless mod.is_a?(String)
|
87
|
+
abort("Can't find #{mod} in #{@module_path}") unless self.installed?(mod)
|
88
|
+
end
|
89
|
+
|
90
|
+
module_objects = resolve_local_module_deps(module_array)
|
91
|
+
|
92
|
+
# Remove the local modules from the list of modules to install
|
93
|
+
# so that the installation process does not overwrite whatever
|
94
|
+
# initiated running puppet-moddeps.
|
95
|
+
module_objects.each do |obj|
|
96
|
+
if module_array.include?(obj.name)
|
97
|
+
module_objects.delete(obj)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# install the needed modules
|
102
|
+
self.install_modules(module_objects)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Test to see if a module's folder is present within the module path.
|
106
|
+
#
|
107
|
+
# @param module_name [String]
|
108
|
+
# The name of a module
|
109
|
+
#
|
110
|
+
# @return [Boolean]
|
111
|
+
# Returns true if found, false otherwise
|
112
|
+
def installed?(module_name)
|
113
|
+
File.directory?("#{@module_path}/#{module_name}")
|
114
|
+
end
|
115
|
+
|
116
|
+
# Determine the character used to separate entries in an operating
|
117
|
+
# system's path environment variable.
|
118
|
+
#
|
119
|
+
# @param os_string [String]
|
120
|
+
# A string representing a host's operating system as returned
|
121
|
+
# by RbConfig::CONFIG['host_os']
|
122
|
+
#
|
123
|
+
# @return [String]
|
124
|
+
# Returns ";" on Windows and ":" on everything else
|
125
|
+
def path_separator(os_string)
|
126
|
+
if (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ os_string) != nil
|
127
|
+
separator = ';'
|
128
|
+
else
|
129
|
+
separator = ':'
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Resolves the dependencies of one or more locally installed modules
|
134
|
+
#
|
135
|
+
# @param modules [Array[String]]
|
136
|
+
# An array of module names
|
137
|
+
#
|
138
|
+
# @return [Array[Puppet::Moddeps::Module]]
|
139
|
+
# An array of module objects representing the modules that need
|
140
|
+
# to be installed to satisfiy the dependencies of the local module(s)
|
141
|
+
def resolve_local_module_deps(modules)
|
142
|
+
# Build the document model from the modules.
|
143
|
+
model = PuppetfileResolver::Puppetfile::Document.new('')
|
144
|
+
|
145
|
+
modules.each do |mod|
|
146
|
+
model.add_module(
|
147
|
+
PuppetfileResolver::Puppetfile::LocalModule.new(mod)
|
148
|
+
)
|
149
|
+
end
|
150
|
+
|
151
|
+
# Make sure the Puppetfile model is valid.
|
152
|
+
unless model.valid?
|
153
|
+
raise "Unable to resolve dependencies for modules: #{modules.map(&:title).join(', ')}"
|
154
|
+
end
|
155
|
+
|
156
|
+
resolver = PuppetfileResolver::Resolver.new(model, @puppet_version)
|
157
|
+
|
158
|
+
# Configure and resolve the dependency graph, catching any errors
|
159
|
+
# raised by puppetfile-resolver and re-raising them as Bolt errors.
|
160
|
+
begin
|
161
|
+
result = resolver.resolve(
|
162
|
+
cache: nil,
|
163
|
+
ui: nil,
|
164
|
+
module_paths: [@module_path],
|
165
|
+
allow_missing_modules: false
|
166
|
+
)
|
167
|
+
rescue StandardError => e
|
168
|
+
raise e.message
|
169
|
+
end
|
170
|
+
|
171
|
+
# Turn specifications into module objects. This will skip over anything that is not
|
172
|
+
# a module specification (i.e. a Puppet version specification).
|
173
|
+
module_objects = result.specifications.each_with_object(Set.new) do |(_name, spec), acc|
|
174
|
+
next unless spec.instance_of? PuppetfileResolver::Models::ModuleSpecification
|
175
|
+
acc << Puppet::Moddeps::Module.new(spec.owner, spec.name, spec.version.to_s)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
# Installs requested modules if they are not already installed.
|
180
|
+
#
|
181
|
+
# @param module_objects [Array[Puppet::Moddeps::Module]]
|
182
|
+
# An array of module objects representing the modules that need
|
183
|
+
# to be installed
|
184
|
+
def install_modules(module_objects)
|
185
|
+
if Array(module_objects).size > 0
|
186
|
+
puts "Modules will be installed into #{@module_path}"
|
187
|
+
|
188
|
+
Array(module_objects).each do |mod|
|
189
|
+
if self.installed?(mod.name) && self.module_versions_match?(mod.owner, mod.name, mod.version)
|
190
|
+
puts "#{mod.owner}-#{mod.name} #{mod.version} is already installed, skipping"
|
191
|
+
else
|
192
|
+
self.call_puppet(mod)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
else
|
196
|
+
puts 'No dependencies were marked for installation.'
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
# Parses the metadata.json file of a module and returns it as Hash
|
201
|
+
#
|
202
|
+
# @param module_name [String]
|
203
|
+
# The name of a module
|
204
|
+
#
|
205
|
+
# @return [Hash]
|
206
|
+
# A hash representing the JSON metadata
|
207
|
+
def parse_metadata(module_name)
|
208
|
+
metadata = File.read("#{@module_path}/#{module_name}/metadata.json")
|
209
|
+
data = JSON.parse(metadata)
|
210
|
+
end
|
211
|
+
|
212
|
+
# Compare the owner, name, and version of an installed module to a
|
213
|
+
# provided set of information.
|
214
|
+
#
|
215
|
+
# @param module_owner [String]
|
216
|
+
# The owner / author of a module. Ex. puppetlabs
|
217
|
+
# @param module_name [String]
|
218
|
+
# The name of a module. Ex. apache
|
219
|
+
# @param module_version [String]
|
220
|
+
# The semantic version of a module. Ex. 5.6.0
|
221
|
+
#
|
222
|
+
# @return [Boolean]
|
223
|
+
# Retruns true if the information matches, false otherwise
|
224
|
+
def module_versions_match?(module_owner, module_name, module_version)
|
225
|
+
metadata = self.parse_metadata(module_name)
|
226
|
+
if metadata['author'].eql?(module_owner) && metadata['version'].eql?(module_version)
|
227
|
+
return true
|
228
|
+
else
|
229
|
+
return false
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
# Shell out to the puppet binary to install a module without dependencies.
|
234
|
+
#
|
235
|
+
# @param module_object [Puppet::Moddeps::Module]
|
236
|
+
# A Module object that represents the module to install
|
237
|
+
def call_puppet(module_object)
|
238
|
+
cmd = "puppet module install --force --ignore-dependencies #{module_object.owner}-#{module_object.name} --version #{module_object.version}"
|
239
|
+
puts "Running \"#{cmd}\""
|
240
|
+
%x(#{cmd})
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|