puppetbox 0.4.1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|