puppetbox 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/puppetbox/driver/vagrant.rb +34 -15
- data/lib/puppetbox/puppet.rb +12 -0
- data/lib/puppetbox/puppetbox.rb +55 -16
- data/lib/puppetbox/util.rb +13 -0
- data/lib/puppetbox/version.rb +1 -1
- data/puppetbox.gemspec +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd53bc360e5558df6c0eb16ffce3ab13b0d21e48
|
4
|
+
data.tar.gz: 120393a564d129bf93a89bc35d378c6ec830dd04
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dd0bcf8e48b6c0451de2aec7c73b4d4e0acba8418c3ad0945cbd7af20efec1c5fa9f51006a15929c2dd979728dec9c0040038400019b42690143da2831122310
|
7
|
+
data.tar.gz: 7fe318dc03b0a0e61c78509ebc014af8d8869cfc19bd858521295ad1dee8f026c44a2d5c31b16b584e6fb51e40a775db8abdb62f173ed82eaba77b71d5632e02
|
@@ -9,8 +9,11 @@ module PuppetBox
|
|
9
9
|
WORKING_DIR_VAGRANT = "vagrant"
|
10
10
|
PUPPET_CODE_MOUNT = "/etc/puppetlabs/code/environments/production"
|
11
11
|
|
12
|
-
# mount spec/
|
13
|
-
|
12
|
+
# mount spec/ into the same directory name inside the VM for simplicity -
|
13
|
+
# now we can easility access fixtures, tests, etc
|
14
|
+
SPEC_ACCEPTANCE_MOUNT = "spec:/spec"
|
15
|
+
|
16
|
+
PUPPET_TESTCASE_DIR = "/testcase"
|
14
17
|
|
15
18
|
def node_name
|
16
19
|
@name
|
@@ -18,15 +21,17 @@ module PuppetBox
|
|
18
21
|
|
19
22
|
def initialize(name, codedir, config, keep_vm:false, working_dir:nil, logger: nil)
|
20
23
|
|
21
|
-
@name
|
22
|
-
@keep_vm
|
23
|
-
@working_dir
|
24
|
-
@
|
25
|
-
@
|
26
|
-
@
|
24
|
+
@name = name
|
25
|
+
@keep_vm = keep_vm
|
26
|
+
@working_dir = working_dir || PuppetBox::WORKING_DIR
|
27
|
+
@vagrant_vm_dir = File.join(@working_dir, WORKING_DIR_VAGRANT)
|
28
|
+
@testcase_dir = File.join(@working_dir, PUPPET_TESTCASE_DIR)
|
29
|
+
@config = config
|
30
|
+
@result = Result.new
|
31
|
+
@logger = Logger.new(logger).logger
|
27
32
|
|
28
33
|
# setup the instance
|
29
|
-
@vom = Vagrantomatic::Vagrantomatic.new(vagrant_vm_dir:@
|
34
|
+
@vom = Vagrantomatic::Vagrantomatic.new(vagrant_vm_dir:@vagrant_vm_dir, logger:@logger)
|
30
35
|
@logger.debug("creating instance metadata for #{@name}")
|
31
36
|
@vm = @vom.instance(@name, config:@config)
|
32
37
|
|
@@ -36,6 +41,10 @@ module PuppetBox
|
|
36
41
|
# ./spec/acceptance directory
|
37
42
|
@vm.add_shared_folder(SPEC_ACCEPTANCE_MOUNT)
|
38
43
|
|
44
|
+
# mount the temporary testcase files (smoketests - the generated files
|
45
|
+
# holding 'include apache', etc)
|
46
|
+
@vm.add_shared_folder("#{@testcase_dir}:#{PUPPET_TESTCASE_DIR}")
|
47
|
+
|
39
48
|
@logger.debug "instance #{name} initialised"
|
40
49
|
end
|
41
50
|
|
@@ -52,9 +61,9 @@ module PuppetBox
|
|
52
61
|
# 2: The run succeeded, and some resources were changed.
|
53
62
|
# 4: The run succeeded, and some resources failed.
|
54
63
|
# 6: The run succeeded, and included both changes and failures.
|
55
|
-
def run_puppet(
|
64
|
+
def run_puppet(puppet_file)
|
56
65
|
status_code, messages = @vm.run(
|
57
|
-
"sudo -i puppet apply --detailed-exitcodes
|
66
|
+
"sudo -i puppet apply --detailed-exitcodes #{puppet_file}"
|
58
67
|
)
|
59
68
|
@result.save(status_code, messages)
|
60
69
|
@result.passed?
|
@@ -64,6 +73,8 @@ module PuppetBox
|
|
64
73
|
def open()
|
65
74
|
# make sure working dir exists...
|
66
75
|
FileUtils.mkdir_p(@working_dir)
|
76
|
+
FileUtils.mkdir_p(@vagrant_vm_dir)
|
77
|
+
FileUtils.mkdir_p(@testcase_dir)
|
67
78
|
@vm.save
|
68
79
|
|
69
80
|
@logger.debug("Instance saved and ready for starting")
|
@@ -73,13 +84,17 @@ module PuppetBox
|
|
73
84
|
# Close a connection to a box (eg stop a vm, probaly doesn't need to do
|
74
85
|
# anything on SSH...)
|
75
86
|
def close()
|
76
|
-
if
|
87
|
+
if @keep_vm
|
88
|
+
vagrant_cmd = "cd #{@vm.vm_instance_dir} && vagrant ssh"
|
89
|
+
@logger.info("VM #{@name} left running on user request, `#{vagrant_cmd}` to access - be sure to clean up your VMs!")
|
90
|
+
else
|
77
91
|
@logger.info("Closing #{@name}")
|
78
92
|
@vm.purge
|
79
93
|
end
|
80
94
|
end
|
81
95
|
|
82
96
|
def reset()
|
97
|
+
@result = Result.new
|
83
98
|
@vm.reset
|
84
99
|
end
|
85
100
|
|
@@ -126,16 +141,20 @@ module PuppetBox
|
|
126
141
|
status
|
127
142
|
end
|
128
143
|
|
129
|
-
def run_puppet_x2(
|
144
|
+
def run_puppet_x2(puppet_file)
|
130
145
|
# if you need to link a module into puppet's modulepath either do it
|
131
146
|
# before running puppet (yet to be supported) or use the @config hash
|
132
147
|
# for vagrant to mount what you need as a shared folder
|
133
|
-
if run_puppet(
|
148
|
+
if run_puppet(puppet_file)
|
134
149
|
# Only do the second run if the first run passes
|
135
|
-
run_puppet(
|
150
|
+
run_puppet(puppet_file)
|
136
151
|
end
|
137
152
|
end
|
138
153
|
|
154
|
+
# noop
|
155
|
+
def sync_testcase(node_name, test_name)
|
156
|
+
end
|
157
|
+
|
139
158
|
end
|
140
159
|
end
|
141
160
|
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module PuppetBox
|
2
|
+
module Puppet
|
3
|
+
def self.include_class(class_name, pre:nil)
|
4
|
+
if pre
|
5
|
+
# apply a prerequisite and make sure there is a trailing newline. this
|
6
|
+
# will be eval'ed directly so make sure there are no mad characters
|
7
|
+
pre = "#{pre}\n"
|
8
|
+
end
|
9
|
+
"#{pre}include #{class_name}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/puppetbox/puppetbox.rb
CHANGED
@@ -3,6 +3,8 @@ require "puppetbox/logger"
|
|
3
3
|
require "puppetbox/nodeset"
|
4
4
|
require "puppetbox/driver/vagrant"
|
5
5
|
require "puppetbox/report"
|
6
|
+
require "puppetbox/puppet"
|
7
|
+
require "puppetbox/util"
|
6
8
|
|
7
9
|
module PuppetBox
|
8
10
|
class PuppetBox
|
@@ -12,7 +14,14 @@ module PuppetBox
|
|
12
14
|
ACCEPTANCE_DEFAULT = "__ALL__"
|
13
15
|
SETUP_SCRIPT_GLOB = "setup.*"
|
14
16
|
|
15
|
-
|
17
|
+
# we write testcases (smoketests) to this directory in our working dir...
|
18
|
+
PUPPET_TESTCASE_TEMPDIR = "testcase"
|
19
|
+
|
20
|
+
# ...and they appear on the system under test at this directory (like a
|
21
|
+
# wormhole) - the driver class is responsible for making this happen
|
22
|
+
PUPPET_TESTCASE_DIR = "/testcase"
|
23
|
+
|
24
|
+
def initialize(logger:nil, nodeset_file: nil, working_dir: nil, keep_test_system:false)
|
16
25
|
# The results of all tests on all driver instances
|
17
26
|
@result_set = ResultSet.new
|
18
27
|
|
@@ -28,19 +37,24 @@ module PuppetBox
|
|
28
37
|
@nodeset = NodeSet.new(nodeset_file)
|
29
38
|
|
30
39
|
@working_dir = working_dir || WORKING_DIR
|
40
|
+
@puppet_test_tempdir = File.join(@working_dir, PUPPET_TESTCASE_TEMPDIR)
|
41
|
+
|
42
|
+
@keep_test_system = keep_test_system
|
31
43
|
end
|
32
44
|
|
33
45
|
|
34
46
|
# Enqueue a test into the `testsuite` for
|
35
|
-
def
|
47
|
+
def enqueue_test_class(node_name, run_from, puppet_class, pre:nil)
|
36
48
|
instantiate_driver(node_name, run_from)
|
37
|
-
@testsuite[
|
38
|
-
|
49
|
+
# eg @testsuite['centos']['apache']='include apache'
|
50
|
+
test_name=puppet_class
|
51
|
+
@testsuite[node_name]["tests"][test_name] = Puppet::include_class(puppet_class, pre:pre)
|
39
52
|
end
|
40
53
|
|
41
54
|
def run_testsuite
|
42
55
|
@testsuite.each { |id, tests|
|
43
|
-
|
56
|
+
# tests for each node
|
57
|
+
run_puppet(tests["instance"], tests["tests"], logger:@logger, reset_after_run:true)
|
44
58
|
}
|
45
59
|
end
|
46
60
|
|
@@ -75,6 +89,7 @@ module PuppetBox
|
|
75
89
|
# "#{repo.tempdir}/etc/puppetlabs/code/environments/production",
|
76
90
|
logger: @logger,
|
77
91
|
working_dir: @working_dir,
|
92
|
+
keep_vm: @keep_test_system
|
78
93
|
)
|
79
94
|
|
80
95
|
# immediately validate the configuration to allow us to fail-fast
|
@@ -85,7 +100,7 @@ module PuppetBox
|
|
85
100
|
|
86
101
|
@testsuite[node_name] = {
|
87
102
|
"instance" => di,
|
88
|
-
"
|
103
|
+
"tests" => {},
|
89
104
|
}
|
90
105
|
end
|
91
106
|
end
|
@@ -155,32 +170,42 @@ module PuppetBox
|
|
155
170
|
end
|
156
171
|
end
|
157
172
|
|
158
|
-
|
159
|
-
|
173
|
+
|
174
|
+
# Run puppet using `driver_instance` to execute `puppet_codes`
|
175
|
+
# @param puppet_test Hash of test names <-> puppet code, eg {"apache"=>"include apache","nginx"=>"include nginx"}}
|
176
|
+
def run_puppet(driver_instance, puppet_tests, logger:nil, reset_after_run:true)
|
160
177
|
# use supplied logger in preference to the default puppetbox logger instance
|
161
178
|
logger = logger || @logger
|
162
|
-
logger.debug("#{driver_instance.node_name} running
|
163
|
-
puppet_classes = Array(puppet_classes)
|
179
|
+
logger.debug("#{driver_instance.node_name} running #{puppet_tests.size} tests")
|
164
180
|
|
165
181
|
if driver_instance.open
|
166
182
|
logger.debug("#{driver_instance.node_name} started")
|
167
183
|
if driver_instance.self_test
|
168
184
|
logger.debug("#{driver_instance.node_name} self_test OK, running puppet")
|
169
|
-
|
185
|
+
puppet_tests.each { |test_name, puppet_code|
|
170
186
|
if @result_set.class_size(driver_instance.node_name) > 0 and reset_after_run
|
171
187
|
# purge and reboot the vm - this will save approximately 1 second
|
172
188
|
# per class on the self-test which we now know will succeed
|
173
189
|
driver_instance.reset
|
174
190
|
end
|
175
|
-
setup_test(driver_instance,
|
176
|
-
logger.info("running test #{driver_instance.node_name} - #{
|
177
|
-
|
178
|
-
|
191
|
+
setup_test(driver_instance, test_name)
|
192
|
+
logger.info("running test #{driver_instance.node_name} - #{test_name}")
|
193
|
+
|
194
|
+
# write out the local test file
|
195
|
+
relative_puppet_file = commit_testcase(
|
196
|
+
puppet_tests, driver_instance.node_name, test_name
|
197
|
+
)
|
198
|
+
driver_instance.sync_testcase(driver_instance.node_name, test_name)
|
199
|
+
|
200
|
+
puppet_file_remote = File.join(PUPPET_TESTCASE_DIR, relative_puppet_file)
|
201
|
+
driver_instance.run_puppet_x2(puppet_file_remote)
|
202
|
+
@logger.debug("Saved result #{driver_instance.node_name} #{test_name} #{driver_instance.result.passed?}")
|
203
|
+
@result_set.save(driver_instance.node_name, test_name, driver_instance.result)
|
179
204
|
|
180
205
|
Report::log_test_result_or_errors(
|
181
206
|
@logger,
|
182
207
|
driver_instance.node_name,
|
183
|
-
|
208
|
+
test_name,
|
184
209
|
driver_instance.result,
|
185
210
|
)
|
186
211
|
}
|
@@ -195,5 +220,19 @@ module PuppetBox
|
|
195
220
|
driver_instance.close
|
196
221
|
end
|
197
222
|
|
223
|
+
#
|
224
|
+
#@param testcases Pass in directly the testcases we are working against, to
|
225
|
+
# handle situations where `run_puppet()` was called directly
|
226
|
+
def commit_testcase(testcases, node_name, test_name)
|
227
|
+
puppet_code = testcases[test_name]
|
228
|
+
relative_filename = Util.test_file_name(node_name, test_name)
|
229
|
+
filename = File.join(@puppet_test_tempdir, relative_filename)
|
230
|
+
FileUtils.mkdir_p(File.dirname(filename))
|
231
|
+
File.write(filename, puppet_code)
|
232
|
+
@logger.debug("Saved testcase #{filename}: #{puppet_code.slice(0,50)}...(ellipsed)")
|
233
|
+
|
234
|
+
relative_filename
|
235
|
+
end
|
236
|
+
|
198
237
|
end
|
199
238
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module PuppetBox
|
2
|
+
module Util
|
3
|
+
|
4
|
+
|
5
|
+
# return the filename that a testcase for a particular test should live in
|
6
|
+
# eg node_name=centos7, test_name=role::base should be in centos7/role__base.pp
|
7
|
+
def self.test_file_name(node_name, test_name)
|
8
|
+
test_name_safe = test_name.gsub(/::/,'__')
|
9
|
+
File.join(node_name, "#{test_name_safe}.pp")
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
data/lib/puppetbox/version.rb
CHANGED
data/puppetbox.gemspec
CHANGED
@@ -23,6 +23,6 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_development_dependency "rake", "~> 10.0"
|
24
24
|
spec.add_development_dependency "rspec", "~> 3.0"
|
25
25
|
|
26
|
-
spec.add_dependency "vagrantomatic", "0.3.
|
26
|
+
spec.add_dependency "vagrantomatic", "0.3.3"
|
27
27
|
spec.add_dependency "colorize"
|
28
28
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puppetbox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Geoff Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-04-
|
11
|
+
date: 2017-04-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - '='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.3.
|
61
|
+
version: 0.3.3
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.3.
|
68
|
+
version: 0.3.3
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: colorize
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -101,10 +101,12 @@ files:
|
|
101
101
|
- lib/puppetbox/driver/vagrant.rb
|
102
102
|
- lib/puppetbox/logger.rb
|
103
103
|
- lib/puppetbox/nodeset.rb
|
104
|
+
- lib/puppetbox/puppet.rb
|
104
105
|
- lib/puppetbox/puppetbox.rb
|
105
106
|
- lib/puppetbox/report.rb
|
106
107
|
- lib/puppetbox/result.rb
|
107
108
|
- lib/puppetbox/result_set.rb
|
109
|
+
- lib/puppetbox/util.rb
|
108
110
|
- lib/puppetbox/version.rb
|
109
111
|
- puppetbox.gemspec
|
110
112
|
homepage: https://github.com/GeoffWilliams/puppetbox
|