beaker 1.17.7 → 1.18.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/HISTORY.md +314 -2
- data/beaker.gemspec +1 -0
- data/lib/beaker/dsl/helpers.rb +3 -3
- data/lib/beaker/dsl/install_utils.rb +83 -25
- data/lib/beaker/host.rb +14 -3
- data/lib/beaker/host/windows.rb +3 -3
- data/lib/beaker/host/windows/pkg.rb +6 -0
- data/lib/beaker/host_prebuilt_steps.rb +0 -4
- data/lib/beaker/hypervisor.rb +3 -1
- data/lib/beaker/hypervisor/aws_sdk.rb +22 -0
- data/lib/beaker/hypervisor/docker.rb +4 -3
- data/lib/beaker/hypervisor/openstack.rb +154 -0
- data/lib/beaker/options/presets.rb +1 -1
- data/lib/beaker/perf.rb +22 -4
- data/lib/beaker/ssh_connection.rb +2 -2
- data/lib/beaker/version.rb +1 -1
- data/spec/beaker/dsl/helpers_spec.rb +1 -1
- data/spec/beaker/dsl/install_utils_spec.rb +45 -1
- data/spec/beaker/host_prebuilt_steps_spec.rb +0 -16
- data/spec/beaker/hypervisor/docker_spec.rb +5 -0
- data/spec/beaker/perf_spec.rb +7 -4
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MzQxM2VhODU1MzlmN2Q3NjRmYmU0Y2ExM2QyMDBiYWNlNjg0ODAwMg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NjQ1YjA0NzYxMTllZDMxYWE1Yjk1MzVjNzY4NzA2NzQ5N2MyNjU2Ng==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NjViZjlhMDg2OWVmNzkzMTUwYmFkODc5MjBhNDJmNGZiNGFlZmMwZGFmMTY4
|
10
|
+
NDkwMWMzMGMzYTE1NmFhMDllYjA4MTUzZmJlOGZhMzkxNjNhZDFjYjdkNDQ2
|
11
|
+
NjRiMjNiZTBjMGI0Y2ZiY2E1NzViM2VmODE2ZGZjMGI5ZmY5OWU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YTU0NWUzMDAyZjM0ODkzNzNlODU0MjZlMGQwZDVmZDA3MmFjOGYwMjA0OTI4
|
14
|
+
ZTdmOGY5NjY5OTQ2OTU4NjI0NmEzYzFlNzRkZmI5YjEyYzNkNmUwODY1MTgy
|
15
|
+
MTZkZjUwZGIxMzZlY2RjZDhkMjM4NDc3Y2JiNzg4OTNhMjM2YzA=
|
data/HISTORY.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# beaker - History
|
2
2
|
## Tags
|
3
|
-
* [LATEST -
|
3
|
+
* [LATEST - 18 Sep, 2014 (116ecd2e)](#LATEST)
|
4
|
+
* [beaker1.17.7 - 2 Sep, 2014 (e47881f0)](#beaker1.17.7)
|
5
|
+
* [beaker1.17.6 - 27 Aug, 2014 (bfb257bf)](#beaker1.17.6)
|
4
6
|
* [beaker1.17.5 - 22 Aug, 2014 (7e553089)](#beaker1.17.5)
|
5
7
|
* [beaker1.17.4 - 21 Aug, 2014 (8e6d070f)](#beaker1.17.4)
|
6
8
|
* [beaker1.17.3 - 20 Aug, 2014 (f8a536c1)](#beaker1.17.3)
|
@@ -58,7 +60,317 @@
|
|
58
60
|
* [pe1.2 - 6 Sep, 2011 (ba3dadd2)](#pe1.2)
|
59
61
|
|
60
62
|
## Details
|
61
|
-
### <a name = "LATEST">LATEST -
|
63
|
+
### <a name = "LATEST">LATEST - 18 Sep, 2014 (116ecd2e)
|
64
|
+
|
65
|
+
* (GEM) version bump for beaker 1.18.0 (116ecd2e)
|
66
|
+
|
67
|
+
* Merge pull request #450 from anodelman/scp-repair (ee03903b)
|
68
|
+
|
69
|
+
|
70
|
+
```
|
71
|
+
Merge pull request #450 from anodelman/scp-repair
|
72
|
+
|
73
|
+
(QENG-1128) Beaker no long auto recursively scps directories to systems under test
|
74
|
+
```
|
75
|
+
* Merge pull request #361 from anodelman/openstack (2e15cdaa)
|
76
|
+
|
77
|
+
|
78
|
+
```
|
79
|
+
Merge pull request #361 from anodelman/openstack
|
80
|
+
|
81
|
+
(QENG-15) support openstack in beaker
|
82
|
+
```
|
83
|
+
* Merge pull request #388 from ferventcoder/ticket/master/allow-git-depth (4d4120a3)
|
84
|
+
|
85
|
+
|
86
|
+
```
|
87
|
+
Merge pull request #388 from ferventcoder/ticket/master/allow-git-depth
|
88
|
+
|
89
|
+
(QENG-1037) Install from git should accept depth
|
90
|
+
```
|
91
|
+
* Merge pull request #435 from leoc/add-prebuilt-packages-to-docker (c0a20691)
|
92
|
+
|
93
|
+
|
94
|
+
```
|
95
|
+
Merge pull request #435 from leoc/add-prebuilt-packages-to-docker
|
96
|
+
|
97
|
+
(gh-426) Add prebuild packages to Dockerfile
|
98
|
+
```
|
99
|
+
* Merge pull request #439 from doug-rosser/perf_fixes (7c68e4da)
|
100
|
+
|
101
|
+
|
102
|
+
```
|
103
|
+
Merge pull request #439 from doug-rosser/perf_fixes
|
104
|
+
|
105
|
+
(QENG-1033) Don't modify constants and properly support all Linux platforms in Perf
|
106
|
+
```
|
107
|
+
* Merge pull request #416 from anodelman/ec2 (de3b3f9d)
|
108
|
+
|
109
|
+
|
110
|
+
```
|
111
|
+
Merge pull request #416 from anodelman/ec2
|
112
|
+
|
113
|
+
(MAINT) add ability to list all instances associated with an ec2 keyname
|
114
|
+
```
|
115
|
+
* (QENG-1033) Remove dead rspec code (c713fdb1)
|
116
|
+
|
117
|
+
* Merge pull request #451 from anodelman/maint (34db9711)
|
118
|
+
|
119
|
+
|
120
|
+
```
|
121
|
+
Merge pull request #451 from anodelman/maint
|
122
|
+
|
123
|
+
(MAINT) broken spec fixes (docker + copy_module_to)
|
124
|
+
```
|
125
|
+
* (MAINT) broken spec fixes (docker + copy_module_to) (98454e51)
|
126
|
+
|
127
|
+
|
128
|
+
```
|
129
|
+
(MAINT) broken spec fixes (docker + copy_module_to)
|
130
|
+
|
131
|
+
- docker spec was still allowing sleeps to execute making things run
|
132
|
+
slow
|
133
|
+
- update copy_module_to spec test to use correct ignore list
|
134
|
+
```
|
135
|
+
* (QENG-1128) Beaker no long auto recursively scps directories... (c89fae53)
|
136
|
+
|
137
|
+
|
138
|
+
```
|
139
|
+
(QENG-1128) Beaker no long auto recursively scps directories...
|
140
|
+
|
141
|
+
to systems under test
|
142
|
+
|
143
|
+
- issue was :recursive variable was being carried over successive calls
|
144
|
+
to scp_to. To prevent this, just set it based upon the file type
|
145
|
+
being called
|
146
|
+
```
|
147
|
+
* Merge pull request #440 from colinPL/qeng989_solaris_gem (34e6474f)
|
148
|
+
|
149
|
+
|
150
|
+
```
|
151
|
+
Merge pull request #440 from colinPL/qeng989_solaris_gem
|
152
|
+
|
153
|
+
(QENG-989) install_puppet_from_gem fails on Solaris
|
154
|
+
```
|
155
|
+
* Merge pull request #412 from anodelman/maint (8e991e18)
|
156
|
+
|
157
|
+
|
158
|
+
```
|
159
|
+
Merge pull request #412 from anodelman/maint
|
160
|
+
|
161
|
+
(QENG-1018) default dev_builds_url in Beaker needs to be updated
|
162
|
+
```
|
163
|
+
* Merge pull request #448 from cyberious/AddIgnores (eb5a99c5)
|
164
|
+
|
165
|
+
|
166
|
+
```
|
167
|
+
Merge pull request #448 from cyberious/AddIgnores
|
168
|
+
|
169
|
+
QENG-1199 add .bundle to ignore list
|
170
|
+
```
|
171
|
+
* QENG-1199 add .bundle to ignore list (314d85ce)
|
172
|
+
|
173
|
+
* (QENG-1033) Move all functionality into the Perf module and sync the rspec tests (64e69a17)
|
174
|
+
|
175
|
+
* Merge pull request #445 from waynr/fix/qeng-1186-beaker-dsl-helpers-puppet-mixup (cbff4759)
|
176
|
+
|
177
|
+
|
178
|
+
```
|
179
|
+
Merge pull request #445 from waynr/fix/qeng-1186-beaker-dsl-helpers-puppet-mixup
|
180
|
+
|
181
|
+
(QENG-1186) Fix Beaker::DSL:Helpers.puppet_{user,group}
|
182
|
+
```
|
183
|
+
* Merge pull request #425 from jtopper/avoid_docker_clean_race (c40c37de)
|
184
|
+
|
185
|
+
|
186
|
+
```
|
187
|
+
Merge pull request #425 from jtopper/avoid_docker_clean_race
|
188
|
+
|
189
|
+
(GH-425) Sleep briefly after killing processes - Docker
|
190
|
+
```
|
191
|
+
* Merge pull request #436 from anodelman/win-fix (de316e3a)
|
192
|
+
|
193
|
+
|
194
|
+
```
|
195
|
+
Merge pull request #436 from anodelman/win-fix
|
196
|
+
|
197
|
+
(QENG-797) Enhance Beaker to look for x64 installers for Windows
|
198
|
+
```
|
199
|
+
* (QENG-1033) Reset additional_pkgs in a way supported by all Ruby versions (9e6b5283)
|
200
|
+
|
201
|
+
* (QENG-1033) additional_pkgs should be a module level variable (6623ec0e)
|
202
|
+
|
203
|
+
* (QENG-1186) Fix Beaker::DSL:Helpers.puppet_{user,group} (5bb6ee4e)
|
204
|
+
|
205
|
+
|
206
|
+
```
|
207
|
+
(QENG-1186) Fix Beaker::DSL:Helpers.puppet_{user,group}
|
208
|
+
|
209
|
+
Looks like the contents of these methods were mixed upwhen originally written.
|
210
|
+
Luckily the puppet user is usually the same as the puppet group.
|
211
|
+
|
212
|
+
Signed-off-by: Wayne <wayne@puppetlabs.com>
|
213
|
+
```
|
214
|
+
* (QENG-1033) combine two conditionals into a single statement (e2e91ccc)
|
215
|
+
|
216
|
+
* (QENG-989) install_puppet_from_gem fails on Solaris (45ac614e)
|
217
|
+
|
218
|
+
|
219
|
+
```
|
220
|
+
(QENG-989) install_puppet_from_gem fails on Solaris
|
221
|
+
|
222
|
+
Trying to install puppet from gems would fail on both Solaris 10 and
|
223
|
+
11. Solaris 10 now has pkgutil and gem symlinked (ln -s) to /usr/bin.
|
224
|
+
Both Solaris versions have puppet-related gems symlinked to /usr/bin
|
225
|
+
after installation. This is to avoid clobbering the PATH.
|
226
|
+
```
|
227
|
+
* (QENG-1129) support win64 open source builds (47bf159f)
|
228
|
+
|
229
|
+
|
230
|
+
```
|
231
|
+
(QENG-1129) support win64 open source builds
|
232
|
+
|
233
|
+
- add ability to install 64 bit windows builds
|
234
|
+
- supported when puppet version is 3.7+ or pe is 3.4+, and install_32 is not set for
|
235
|
+
host or globally
|
236
|
+
- correctly update path post pe/puppet installation
|
237
|
+
```
|
238
|
+
* (QENG-1026) Add support for x64 PE windows to Beaker (59a39bd7)
|
239
|
+
|
240
|
+
|
241
|
+
```
|
242
|
+
(QENG-1026) Add support for x64 PE windows to Beaker
|
243
|
+
|
244
|
+
- default to installing 64 bit builds on 64 bit windows
|
245
|
+
- support install_32 host option, true = install 32 bit no matter the
|
246
|
+
arch, false/unset = install 64 bit on 64 bit, otherwise 32 bit
|
247
|
+
```
|
248
|
+
* (QENG-797) Enhance Beaker to look for x64 installers for Windows (066dae5d)
|
249
|
+
|
250
|
+
|
251
|
+
```
|
252
|
+
(QENG-797) Enhance Beaker to look for x64 installers for Windows
|
253
|
+
|
254
|
+
- add ability to install 64 bit pe builds (available for pe 3.4)
|
255
|
+
- add is_x86_64? method to host, convenience method for determining arch
|
256
|
+
of host
|
257
|
+
```
|
258
|
+
* (gh-426) Add prebuild packages to Dockerfile (f4085aca)
|
259
|
+
|
260
|
+
|
261
|
+
```
|
262
|
+
(gh-426) Add prebuild packages to Dockerfile
|
263
|
+
|
264
|
+
Without this patch every time the specs run, prebuilt packages are
|
265
|
+
installed to the new docker image. Even when preserving the image.
|
266
|
+
To increase the speed of the test suite we install those packages when
|
267
|
+
creating the Docker image. The `HostPrebuiltSteps` checks whether those
|
268
|
+
are installed and does not do anything directly starting to execute the
|
269
|
+
specs inside the image.
|
270
|
+
```
|
271
|
+
* (GH-425) Sleep after killing processes (18699dc4)
|
272
|
+
|
273
|
+
|
274
|
+
```
|
275
|
+
(GH-425) Sleep after killing processes
|
276
|
+
|
277
|
+
This avoids a race condition in which the killed processes haven't
|
278
|
+
exited by the time we try and unmount the root fs and the call to
|
279
|
+
container.delete errors.
|
280
|
+
```
|
281
|
+
* (MAINT) add ability to list all instances associated with an ec2 keyname (d5ad9e35)
|
282
|
+
|
283
|
+
|
284
|
+
```
|
285
|
+
(MAINT) add ability to list all instances associated with an ec2 keyname
|
286
|
+
|
287
|
+
- convenience function for listing all instances associated with a
|
288
|
+
provided keyname, useful for tracking what's happening in ec2
|
289
|
+
```
|
290
|
+
* (QENG-1018) default dev_builds_url in Beaker needs to be updated (1b2a935f)
|
291
|
+
|
292
|
+
|
293
|
+
```
|
294
|
+
(QENG-1018) default dev_builds_url in Beaker needs to be updated
|
295
|
+
|
296
|
+
- update to builds.delivery.puppetlabs.net
|
297
|
+
```
|
298
|
+
* (QENG-1037) Install from git should accept depth (ffcddcc0)
|
299
|
+
|
300
|
+
|
301
|
+
```
|
302
|
+
(QENG-1037) Install from git should accept depth
|
303
|
+
|
304
|
+
When installing from larger repositories, being able to specify depth can cut
|
305
|
+
the time of git checkout in half. This becomes especially helpful when you are
|
306
|
+
checking out multiple repositories.
|
307
|
+
Due to the older git on some of the templates, this provides the older
|
308
|
+
--branch name --depth 1 commands, which means when using depth, one should
|
309
|
+
ensure the rev passed is a branch and not a single commit. Alternatively one
|
310
|
+
can add depth_branch => 'name' to repository and have that used instead of rev.
|
311
|
+
```
|
312
|
+
* (maint) formatting (239d8054)
|
313
|
+
|
314
|
+
|
315
|
+
```
|
316
|
+
(maint) formatting
|
317
|
+
|
318
|
+
This removes trailing whitespaces in install_utils.rb
|
319
|
+
```
|
320
|
+
* Add Enterprise Linux (el) (3f2bb69b)
|
321
|
+
|
322
|
+
* (QENG-15) beaker openstack support (EXPERIMENTAL) (745f1a4a)
|
323
|
+
|
324
|
+
|
325
|
+
```
|
326
|
+
(QENG-15) beaker openstack support (EXPERIMENTAL)
|
327
|
+
|
328
|
+
- experimental code to support openstack, may be missing configuration
|
329
|
+
steps or otherwise be incomplete
|
330
|
+
- should be used as a basis for further beaker openstack infrastructure
|
331
|
+
```
|
332
|
+
### <a name = "beaker1.17.7">beaker1.17.7 - 2 Sep, 2014 (e47881f0)
|
333
|
+
|
334
|
+
* Merge pull request #444 from branan/ship_1_17_7 (e47881f0)
|
335
|
+
|
336
|
+
|
337
|
+
```
|
338
|
+
Merge pull request #444 from branan/ship_1_17_7
|
339
|
+
|
340
|
+
(maint) Bump version for 1.17.7 release
|
341
|
+
```
|
342
|
+
* (maint) Bump version for 1.17.7 release (0cb30f18)
|
343
|
+
|
344
|
+
* Merge pull request #443 from briancain/maint/master/add-node-to-classifier (701f81c2)
|
345
|
+
|
346
|
+
|
347
|
+
```
|
348
|
+
Merge pull request #443 from briancain/maint/master/add-node-to-classifier
|
349
|
+
|
350
|
+
(QENG-1182) Add node to classifier prior to adding pe_repo class
|
351
|
+
```
|
352
|
+
* (QENG-1182) Add node to classifier prior to adding pe_repo class (00b2f458)
|
353
|
+
|
354
|
+
|
355
|
+
```
|
356
|
+
(QENG-1182) Add node to classifier prior to adding pe_repo class
|
357
|
+
|
358
|
+
Prior to this commit, beaker would make the assumption that a node had
|
359
|
+
already checked into the classifier. This commit changes that by
|
360
|
+
ensuring that the node is in the classifier before giving it the pe_repo
|
361
|
+
class.
|
362
|
+
```
|
363
|
+
### <a name = "beaker1.17.6">beaker1.17.6 - 27 Aug, 2014 (bfb257bf)
|
364
|
+
|
365
|
+
* Merge pull request #441 from anodelman/make-gem (bfb257bf)
|
366
|
+
|
367
|
+
|
368
|
+
```
|
369
|
+
Merge pull request #441 from anodelman/make-gem
|
370
|
+
|
371
|
+
create beaker 1.17.6 gem
|
372
|
+
```
|
373
|
+
* (HISTORY) update history for 1.17.6 gem (a7ee6c69)
|
62
374
|
|
63
375
|
* (GEM) version bump for 1.17.6 gem (71be2050)
|
64
376
|
|
data/beaker.gemspec
CHANGED
@@ -45,6 +45,7 @@ Gem::Specification.new do |s|
|
|
45
45
|
s.add_runtime_dependency 'google-api-client', '~> 0.7.1'
|
46
46
|
s.add_runtime_dependency 'aws-sdk', '1.42.0'
|
47
47
|
s.add_runtime_dependency 'docker-api' unless RUBY_VERSION < '1.9'
|
48
|
+
s.add_runtime_dependency 'fog', '~> 1.22.1'
|
48
49
|
|
49
50
|
# These are transitive dependencies that we include or pin to because...
|
50
51
|
# Ruby 1.8 compatibility
|
data/lib/beaker/dsl/helpers.rb
CHANGED
@@ -28,7 +28,7 @@ module Beaker
|
|
28
28
|
# @api dsl
|
29
29
|
module Helpers
|
30
30
|
|
31
|
-
PUPPET_MODULE_INSTALL_IGNORE = ['.git', '.idea', '.vagrant', '.vendor', 'acceptance', 'spec', 'tests', 'log']
|
31
|
+
PUPPET_MODULE_INSTALL_IGNORE = ['.bundle', '.git', '.idea', '.vagrant', '.vendor', 'acceptance', 'spec', 'tests', 'log']
|
32
32
|
|
33
33
|
# @!macro common_opts
|
34
34
|
# @param [Hash{Symbol=>String}] opts Options to alter execution.
|
@@ -476,7 +476,7 @@ module Beaker
|
|
476
476
|
# @note This method assumes puppet is installed on the host.
|
477
477
|
#
|
478
478
|
def puppet_user(host)
|
479
|
-
return host.puppet('master')['
|
479
|
+
return host.puppet('master')['user']
|
480
480
|
end
|
481
481
|
|
482
482
|
# Return the name of the puppet group.
|
@@ -486,7 +486,7 @@ module Beaker
|
|
486
486
|
# @note This method assumes puppet is installed on the host.
|
487
487
|
#
|
488
488
|
def puppet_group(host)
|
489
|
-
return host.puppet('master')['
|
489
|
+
return host.puppet('master')['group']
|
490
490
|
end
|
491
491
|
|
492
492
|
# @!visibility private
|
@@ -101,14 +101,25 @@ module Beaker
|
|
101
101
|
#
|
102
102
|
# @see #find_git_repo_versions
|
103
103
|
def install_from_git host, path, repository
|
104
|
-
name
|
105
|
-
repo
|
106
|
-
rev
|
107
|
-
|
104
|
+
name = repository[:name]
|
105
|
+
repo = repository[:path]
|
106
|
+
rev = repository[:rev]
|
107
|
+
depth = repository[:depth]
|
108
|
+
depth_branch = repository[:depth_branch]
|
109
|
+
target = "#{path}/#{name}"
|
110
|
+
|
111
|
+
if (depth_branch.nil?)
|
112
|
+
depth_branch = rev
|
113
|
+
end
|
114
|
+
|
115
|
+
clone_cmd = "git clone #{repo} #{target}"
|
116
|
+
if (depth)
|
117
|
+
clone_cmd = "git clone --branch #{depth_branch} --depth #{depth} #{repo} #{target}"
|
118
|
+
end
|
108
119
|
|
109
120
|
step "Clone #{repo} if needed" do
|
110
121
|
on host, "test -d #{path} || mkdir -p #{path}"
|
111
|
-
on host, "test -d #{target} ||
|
122
|
+
on host, "test -d #{target} || #{clone_cmd}"
|
112
123
|
end
|
113
124
|
|
114
125
|
step "Update #{name} and check out revision #{rev}" do
|
@@ -152,10 +163,9 @@ module Beaker
|
|
152
163
|
def installer_cmd(host, opts)
|
153
164
|
version = host['pe_ver'] || opts[:pe_ver]
|
154
165
|
if host['platform'] =~ /windows/
|
155
|
-
version = host[:pe_ver] || opts['pe_ver_win']
|
156
166
|
log_file = "#{File.basename(host['working_dir'])}.log"
|
157
167
|
pe_debug = host[:pe_debug] || opts[:pe_debug] ? " && cat #{log_file}" : ''
|
158
|
-
"cd #{host['working_dir']} && cmd /C 'start /w msiexec.exe /qn /L*V #{log_file} /i
|
168
|
+
"cd #{host['working_dir']} && cmd /C 'start /w msiexec.exe /qn /L*V #{log_file} /i #{host['dist']}.msi PUPPET_MASTER_SERVER=#{master} PUPPET_AGENT_CERTNAME=#{host}'#{pe_debug}"
|
159
169
|
elsif host['platform'] =~ /osx/
|
160
170
|
version = host['pe_ver'] || opts[:pe_ver]
|
161
171
|
pe_debug = host[:pe_debug] || opts[:pe_debug] ? ' -verboseR' : ''
|
@@ -307,7 +317,7 @@ module Beaker
|
|
307
317
|
path = host['pe_dir'] || opts[:pe_dir]
|
308
318
|
local = File.directory?(path)
|
309
319
|
version = host['pe_ver'] || opts[:pe_ver_win]
|
310
|
-
filename = "
|
320
|
+
filename = "#{host['dist']}"
|
311
321
|
extension = ".msi"
|
312
322
|
if local
|
313
323
|
if not File.exists?("#{path}/#{filename}#{extension}")
|
@@ -431,6 +441,17 @@ module Beaker
|
|
431
441
|
elsif host['platform'] =~ /osx/
|
432
442
|
version = host['pe_ver'] || opts[:pe_ver]
|
433
443
|
host['dist'] = "puppet-enterprise-#{version}-#{host['platform']}"
|
444
|
+
elsif host['platform'] =~ /windows/
|
445
|
+
version = host[:pe_ver] || opts['pe_ver_win']
|
446
|
+
#only install 64bit builds if
|
447
|
+
# - we are on pe version 3.4+
|
448
|
+
# - we do not have install_32 set on host
|
449
|
+
# - we do not have install_32 set globally
|
450
|
+
if !(version_is_less(version, '3.4')) and host.is_x86_64? and not host['install_32'] and not opts['install_32']
|
451
|
+
host['dist'] = "puppet-enterprise-#{version}-x64"
|
452
|
+
else
|
453
|
+
host['dist'] = "puppet-enterprise-#{version}"
|
454
|
+
end
|
434
455
|
end
|
435
456
|
host['working_dir'] = host.tmpdir(Time.new.strftime("%Y-%m-%d_%H.%M.%S"))
|
436
457
|
end
|
@@ -634,11 +655,11 @@ module Beaker
|
|
634
655
|
# Puppet via gem.
|
635
656
|
# @option opts [String] :release The major release of the OS
|
636
657
|
# @option opts [String] :family The OS family (one of 'el' or 'fedora')
|
637
|
-
#
|
658
|
+
#
|
638
659
|
# @return nil
|
639
660
|
# @api private
|
640
661
|
def install_puppet_from_rpm( host, opts )
|
641
|
-
release_package_string = "http://yum.puppetlabs.com/puppetlabs-release-#{opts[:family]}-#{opts[:release]}.noarch.rpm"
|
662
|
+
release_package_string = "http://yum.puppetlabs.com/puppetlabs-release-#{opts[:family]}-#{opts[:release]}.noarch.rpm"
|
642
663
|
|
643
664
|
on host, "rpm -ivh #{release_package_string}"
|
644
665
|
|
@@ -661,7 +682,7 @@ module Beaker
|
|
661
682
|
# @option opts [String] :version The version of Puppet to install, if nil installs latest version
|
662
683
|
# @option opts [String] :facter_version The version of Facter to install, if nil installs latest version
|
663
684
|
# @option opts [String] :hiera_version The version of Hiera to install, if nil installs latest version
|
664
|
-
#
|
685
|
+
#
|
665
686
|
# @return nil
|
666
687
|
# @api private
|
667
688
|
def install_puppet_from_deb( host, opts )
|
@@ -698,20 +719,32 @@ module Beaker
|
|
698
719
|
# @param [Host] host The host to install packages on
|
699
720
|
# @param [Hash{Symbol=>String}] opts An options hash
|
700
721
|
# @option opts [String] :version The version of Puppet to install, required
|
701
|
-
#
|
722
|
+
#
|
702
723
|
# @return nil
|
703
724
|
# @api private
|
704
725
|
def install_puppet_from_msi( host, opts )
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
#
|
709
|
-
|
710
|
-
|
726
|
+
#only install 64bit builds if
|
727
|
+
# - we are on puppet version 3.7+
|
728
|
+
# - we do not have install_32 set on host
|
729
|
+
# - we do not have install_32 set globally
|
730
|
+
version = opts[:version]
|
731
|
+
if !(version_is_less(version, '3.7')) and host.is_x86_64? and not host['install_32'] and not opts['install_32']
|
732
|
+
host['dist'] = "puppet-#{version}-x64"
|
711
733
|
else
|
712
|
-
|
734
|
+
host['dist'] = "puppet-#{version}"
|
713
735
|
end
|
714
|
-
|
736
|
+
link = "http://downloads.puppetlabs.com/windows/#{host['dist']}.msi"
|
737
|
+
if not link_exists?( link )
|
738
|
+
raise "Puppet #{version} at #{link} does not exist!"
|
739
|
+
end
|
740
|
+
on host, "curl -O #{link}"
|
741
|
+
on host, "msiexec /qn /i #{host['dist']}.msi"
|
742
|
+
|
743
|
+
#Because the msi installer doesn't add Puppet to the environment path
|
744
|
+
#Add both potential paths for simplicity
|
745
|
+
#NOTE - this is unnecessary if the host has been correctly identified as 'foss' during set up
|
746
|
+
puppetbin_path = "\"/cygdrive/c/Program Files (x86)/Puppet Labs/Puppet/bin\":\"/cygdrive/c/Program Files/Puppet Labs/Puppet/bin\""
|
747
|
+
on host, %Q{ echo 'export PATH=$PATH:#{puppetbin_path}' > /etc/bash.bashrc }
|
715
748
|
end
|
716
749
|
|
717
750
|
# Installs Puppet and dependencies from dmg
|
@@ -721,7 +754,7 @@ module Beaker
|
|
721
754
|
# @option opts [String] :version The version of Puppet to install, required
|
722
755
|
# @option opts [String] :facter_version The version of Facter to install, required
|
723
756
|
# @option opts [String] :hiera_version The version of Hiera to install, required
|
724
|
-
#
|
757
|
+
#
|
725
758
|
# @return nil
|
726
759
|
# @api private
|
727
760
|
def install_puppet_from_dmg( host, opts )
|
@@ -749,20 +782,25 @@ module Beaker
|
|
749
782
|
# @option opts [String] :version The version of Puppet to install, if nil installs latest
|
750
783
|
# @option opts [String] :facter_version The version of Facter to install, if nil installs latest
|
751
784
|
# @option opts [String] :hiera_version The version of Hiera to install, if nil installs latest
|
752
|
-
#
|
785
|
+
#
|
753
786
|
# @return nil
|
754
787
|
# @raise [StandardError] if gem does not exist on target host
|
755
788
|
# @api private
|
756
789
|
def install_puppet_from_gem( host, opts )
|
790
|
+
# There are a lot of special things to do for Solaris and Solaris 10.
|
791
|
+
# This is easier than checking host['platform'] every time.
|
792
|
+
is_solaris10 = host['platform'] =~ /solaris-10/
|
793
|
+
is_solaris = host['platform'] =~ /solaris/
|
794
|
+
|
757
795
|
# Hosts may be provisioned with csw but pkgutil won't be in the
|
758
796
|
# PATH by default to avoid changing the behavior for Puppet's tests
|
759
|
-
if
|
797
|
+
if is_solaris10
|
760
798
|
on host, 'ln -s /opt/csw/bin/pkgutil /usr/bin/pkgutil'
|
761
799
|
end
|
762
800
|
|
763
801
|
# Solaris doesn't necessarily have this, but gem needs it
|
764
|
-
if
|
765
|
-
on host, 'mkdir -p /var/lib'
|
802
|
+
if is_solaris
|
803
|
+
on host, 'mkdir -p /var/lib'
|
766
804
|
end
|
767
805
|
|
768
806
|
unless host.check_for_command( 'gem' )
|
@@ -779,6 +817,11 @@ module Beaker
|
|
779
817
|
host.install_package gempkg
|
780
818
|
end
|
781
819
|
|
820
|
+
# Link 'gem' to /usr/bin instead of adding /opt/csw/bin to PATH.
|
821
|
+
if is_solaris10
|
822
|
+
on host, 'ln -s /opt/csw/bin/gem /usr/bin/gem'
|
823
|
+
end
|
824
|
+
|
782
825
|
if host['platform'] =~ /debian|ubuntu|solaris/
|
783
826
|
gem_env = YAML.load( on( host, 'gem environment' ).stdout )
|
784
827
|
gem_paths_array = gem_env['RubyGems Environment'].find {|h| h['GEM PATHS'] != nil }['GEM PATHS']
|
@@ -796,6 +839,21 @@ module Beaker
|
|
796
839
|
|
797
840
|
ver_cmd = opts[:version] ? "-v#{opts[:version]}" : ''
|
798
841
|
on host, "gem install puppet #{ver_cmd} --no-ri --no-rdoc"
|
842
|
+
|
843
|
+
# Similar to the treatment of 'gem' above.
|
844
|
+
# This avoids adding /opt/csw/bin to PATH.
|
845
|
+
if is_solaris
|
846
|
+
gem_env = YAML.load( on( host, 'gem environment' ).stdout )
|
847
|
+
# This is the section we want - this has the dir where gem executables go.
|
848
|
+
env_sect = 'EXECUTABLE DIRECTORY'
|
849
|
+
# Get the directory where 'gem' installs executables.
|
850
|
+
# On Solaris 10 this is usually /opt/csw/bin
|
851
|
+
gem_exec_dir = gem_env['RubyGems Environment'].find {|h| h[env_sect] != nil }[env_sect]
|
852
|
+
|
853
|
+
on host, "ln -s #{gem_exec_dir}/hiera /usr/bin/hiera"
|
854
|
+
on host, "ln -s #{gem_exec_dir}/facter /usr/bin/facter"
|
855
|
+
on host, "ln -s #{gem_exec_dir}/puppet /usr/bin/puppet"
|
856
|
+
end
|
799
857
|
end
|
800
858
|
|
801
859
|
|
data/lib/beaker/host.rb
CHANGED
@@ -192,6 +192,18 @@ module Beaker
|
|
192
192
|
self[:ip] ||= get_ip
|
193
193
|
end
|
194
194
|
|
195
|
+
#Examine the host system to determine the architecture
|
196
|
+
#@return [Boolean] true if x86_64, false otherwise
|
197
|
+
def determine_if_x86_64
|
198
|
+
result = exec(Beaker::Command.new("arch | grep x86_64"), :acceptable_exit_codes => (0...127))
|
199
|
+
result.exit_code == 0
|
200
|
+
end
|
201
|
+
|
202
|
+
#@return [Boolean] true if x86_64, false otherwise
|
203
|
+
def is_x86_64?
|
204
|
+
@x86_64 ||= determine_if_x86_64
|
205
|
+
end
|
206
|
+
|
195
207
|
def connection
|
196
208
|
@connection ||= SshConnection.connect( reachable_name,
|
197
209
|
self['user'],
|
@@ -251,13 +263,12 @@ module Beaker
|
|
251
263
|
result.exit_code == 0
|
252
264
|
end
|
253
265
|
|
254
|
-
# scp files from the localhost to this test host
|
266
|
+
# scp files from the localhost to this test host, if a directory is provided it is recursively copied
|
255
267
|
# @param source [String] The path to the file/dir to upload
|
256
268
|
# @param target [String] The destination path on the host
|
257
269
|
# @param [Hash{Symbol=>String}] options Options to alter execution
|
258
|
-
# @option options [Boolean] :recursive Should we copy recursively? Defaults to 'True' in case of a directory source.
|
259
270
|
# @option options [Array<String>] :ignore An array of file/dir paths that will not be copied to the host
|
260
|
-
def do_scp_to source, target, options
|
271
|
+
def do_scp_to source, target, options = {}
|
261
272
|
@logger.debug "localhost $ scp #{source} #{@name}:#{target}"
|
262
273
|
|
263
274
|
result = Result.new(@name, [source, target])
|
data/lib/beaker/host/windows.rb
CHANGED
@@ -25,8 +25,8 @@ module Windows
|
|
25
25
|
'puppetvardir' => '`cygpath -smF 35`/PuppetLabs/puppet/var',
|
26
26
|
'distmoduledir' => '`cygpath -smF 35`/PuppetLabs/puppet/etc/modules',
|
27
27
|
'sitemoduledir' => 'C:/usr/share/puppet/modules',
|
28
|
-
#if an x86
|
29
|
-
'puppetbindir' => '$( [ -d "/cygdrive/c/Program Files (x86)" ] && echo "/cygdrive/c/Program Files (x86)" || echo "/cygdrive/c/Program Files" )/Puppet Labs/Puppet Enterprise/bin',
|
28
|
+
#if an x86 Puppet Labs dir exists then use it, default to non-x86 Program Files directory
|
29
|
+
'puppetbindir' => '$( [ -d "/cygdrive/c/Program Files (x86)/Puppet Labs/Puppet Enterprise/bin" ] && echo "/cygdrive/c/Program Files (x86)" || echo "/cygdrive/c/Program Files" )/Puppet Labs/Puppet Enterprise/bin',
|
30
30
|
'pathseparator' => ';',
|
31
31
|
})
|
32
32
|
end
|
@@ -44,7 +44,7 @@ module Windows
|
|
44
44
|
'hieralibdir' => '`cygpath -w /opt/puppet-git-repos/hiera/lib`',
|
45
45
|
'hierapuppetlibdir' => '`cygpath -w /opt/puppet-git-repos/hiera-puppet/lib`',
|
46
46
|
# PATH related variables need to be Unix, which cygwin converts
|
47
|
-
'puppetbindir' => '$( [ -d "/cygdrive/c/Program Files (x86)" ] && echo "/cygdrive/c/Program Files (x86)" || echo "/cygdrive/c/Program Files" )/Puppet Labs/Puppet/bin',
|
47
|
+
'puppetbindir' => '$( [ -d "/cygdrive/c/Program Files (x86)/Puppet Labs/Puppet/bin" ] && echo "/cygdrive/c/Program Files (x86)" || echo "/cygdrive/c/Program Files" )/Puppet Labs/Puppet/bin',
|
48
48
|
'hierabindir' => '/opt/puppet-git-repos/hiera/bin',
|
49
49
|
'pathseparator' => ';',
|
50
50
|
})
|
@@ -35,6 +35,12 @@ module Windows::Pkg
|
|
35
35
|
raise "Package #{name} cannot be uninstalled on #{self}"
|
36
36
|
end
|
37
37
|
|
38
|
+
#Examine the host system to determine the architecture, overrides default host determine_if_x86_64 so that wmic is used
|
39
|
+
#@return [Boolean] true if x86_64, false otherwise
|
40
|
+
def determine_if_x86_64
|
41
|
+
identify_windows_architecture =~ /64/
|
42
|
+
end
|
43
|
+
|
38
44
|
private
|
39
45
|
|
40
46
|
# @api private
|
@@ -77,10 +77,6 @@ module Beaker
|
|
77
77
|
# @option opts [Beaker::Logger] :logger A {Beaker::Logger} object
|
78
78
|
def validate_host host, opts
|
79
79
|
logger = opts[:logger]
|
80
|
-
if opts[:collect_perf_data]
|
81
|
-
UNIX_PACKAGES << "sysstat" if !UNIX_PACKAGES.include? "sysstat"
|
82
|
-
SLES_PACKAGES << "sysstat" if !SLES_PACKAGES.include? "sysstat"
|
83
|
-
end
|
84
80
|
block_on host do |host|
|
85
81
|
case
|
86
82
|
when host['platform'] =~ /sles-/
|
data/lib/beaker/hypervisor.rb
CHANGED
@@ -44,6 +44,8 @@ module Beaker
|
|
44
44
|
Beaker::GoogleCompute
|
45
45
|
when /docker/
|
46
46
|
Beaker::Docker
|
47
|
+
when /openstack/
|
48
|
+
Beaker::OpenStack
|
47
49
|
when /none/
|
48
50
|
Beaker::Hypervisor
|
49
51
|
else
|
@@ -108,6 +110,6 @@ module Beaker
|
|
108
110
|
end
|
109
111
|
end
|
110
112
|
|
111
|
-
[ 'vsphere_helper', 'vagrant', 'fusion', 'blimper', 'aws_sdk', 'vsphere', 'vcloud', 'vcloud_pooled', 'aixer', 'solaris', 'docker', 'google_compute' ].each do |lib|
|
113
|
+
[ 'vsphere_helper', 'vagrant', 'fusion', 'blimper', 'aws_sdk', 'vsphere', 'vcloud', 'vcloud_pooled', 'aixer', 'solaris', 'docker', 'google_compute', 'openstack' ].each do |lib|
|
112
114
|
require "beaker/hypervisor/#{lib}"
|
113
115
|
end
|
@@ -88,6 +88,28 @@ module Beaker
|
|
88
88
|
nil #void
|
89
89
|
end
|
90
90
|
|
91
|
+
#Print instances to the logger. Instances will be from all regions associated with provided key name and
|
92
|
+
#limited by regex compared to instance status. Defaults to running instances.
|
93
|
+
#@param [String] key The key_name to match for
|
94
|
+
#@param [Regex] status The regular expression to match against the instance's status
|
95
|
+
def log_instances(key = key_name, status = /running/)
|
96
|
+
instances = []
|
97
|
+
@ec2.regions.each do |region|
|
98
|
+
@logger.debug "Reviewing: #{region.name}"
|
99
|
+
@ec2.regions[region.name].instances.each do |instance|
|
100
|
+
if (instance.key_name =~ /#{key}/) and (instance.status.to_s =~ status)
|
101
|
+
instances << instance
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
output = ""
|
106
|
+
instances.each do |instance|
|
107
|
+
output << "#{instance.id} keyname: #{instance.key_name}, dns name: #{instance.dns_name}, private ip: #{instance.private_ip_address}, ip: #{instance.ip_address}, launch time #{instance.launch_time}, status: #{instance.status}\n"
|
108
|
+
end
|
109
|
+
@logger.notify("aws-sdk: List instances (keyname: #{key})")
|
110
|
+
@logger.notify("#{output}")
|
111
|
+
end
|
112
|
+
|
91
113
|
#Shutdown and destroy ec2 instances idenfitied by key that have been alive longer than ZOMBIE hours.
|
92
114
|
#@param [Integer] max_age The age in hours that a machine needs to be older than to be considered a zombie
|
93
115
|
#@param [String] key The key_name to match for
|
@@ -64,6 +64,7 @@ module Beaker
|
|
64
64
|
@logger.debug("stop container #{container.id}")
|
65
65
|
begin
|
66
66
|
container.stop
|
67
|
+
sleep 2 # avoid a race condition where the root FS can't unmount
|
67
68
|
rescue Excon::Errors::ClientError => e
|
68
69
|
@logger.warn("stop of container #{container.id} failed: #{e.response.body}")
|
69
70
|
end
|
@@ -112,19 +113,19 @@ module Beaker
|
|
112
113
|
when /ubuntu/, /debian/
|
113
114
|
dockerfile += <<-EOF
|
114
115
|
RUN apt-get update
|
115
|
-
RUN apt-get install -y openssh-server openssh-client
|
116
|
+
RUN apt-get install -y openssh-server openssh-client #{Beaker::HostPrebuiltSteps::DEBIAN_PACKAGES.join(' ')}
|
116
117
|
EOF
|
117
118
|
when /^el-/, /centos/, /fedora/, /redhat/
|
118
119
|
dockerfile += <<-EOF
|
119
120
|
RUN yum clean all
|
120
|
-
RUN yum install -y sudo openssh-server openssh-clients
|
121
|
+
RUN yum install -y sudo openssh-server openssh-clients #{Beaker::HostPrebuiltSteps::UNIX_PACKAGES.join(' ')}
|
121
122
|
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
|
122
123
|
RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
|
123
124
|
EOF
|
124
125
|
when /opensuse/, /sles/
|
125
126
|
sshd_options = '-o "PermitRootLogin yes" -o "PasswordAuthentication yes" -o "UsePAM no"'
|
126
127
|
dockerfile += <<-EOF
|
127
|
-
RUN zypper -n in openssh
|
128
|
+
RUN zypper -n in openssh #{Beaker::HostPrebuiltSteps::SLES_PACKAGES.join(' ')}
|
128
129
|
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
|
129
130
|
RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
|
130
131
|
EOF
|
@@ -0,0 +1,154 @@
|
|
1
|
+
module Beaker
|
2
|
+
#Beaker support for OpenStack
|
3
|
+
#This code is EXPERIMENTAL!
|
4
|
+
#Please file any issues/concerns at https://github.com/puppetlabs/beaker/issues
|
5
|
+
class OpenStack < Beaker::Hypervisor
|
6
|
+
|
7
|
+
SLEEPWAIT = 5
|
8
|
+
|
9
|
+
#Create a new instance of the OpenStack hypervisor object
|
10
|
+
#@param [<Host>] openstack_hosts The array of OpenStack hosts to provision
|
11
|
+
#@param [Hash{Symbol=>String}] options The options hash containing configuration values
|
12
|
+
#@option options [String] :openstack_api_key The key to access the OpenStack instance with (required)
|
13
|
+
#@option options [String] :openstack_username The username to access the OpenStack instance with (required)
|
14
|
+
#@option options [String] :openstack_auth_url The URL to access the OpenStack instance with (required)
|
15
|
+
#@option options [String] :openstack_tenant The tenant to access the OpenStack instance with (required)
|
16
|
+
#@option options [String] :openstack_network The network that each OpenStack instance should be contacted through (required)
|
17
|
+
#@option options [String] :openstack_keyname The name of an existing key pair that should be auto-loaded onto each
|
18
|
+
# OpenStack instance (optional)
|
19
|
+
#@option options [String] :jenkins_build_url Added as metadata to each OpenStack instance
|
20
|
+
#@option options [String] :department Added as metadata to each OpenStack instance
|
21
|
+
#@option options [String] :project Added as metadata to each OpenStack instance
|
22
|
+
#@option options [Integer] :timeout The amount of time to attempt execution before quiting and exiting with failure
|
23
|
+
def initialize(openstack_hosts, options)
|
24
|
+
require 'fog'
|
25
|
+
@options = options
|
26
|
+
@logger = options[:logger]
|
27
|
+
@hosts = openstack_hosts
|
28
|
+
@vms = []
|
29
|
+
|
30
|
+
raise 'You must specify an Openstack API key (:oopenstack_api_key) for OpenStack instances!' unless @options[:openstack_api_key]
|
31
|
+
raise 'You must specify an Openstack username (:openstack_username) for OpenStack instances!' unless @options[:openstack_username]
|
32
|
+
raise 'You must specify an Openstack auth URL (:openstack_auth_url) for OpenStack instances!' unless @options[:openstack_auth_url]
|
33
|
+
raise 'You must specify an Openstack tenant (:openstack_tenant) for OpenStack instances!' unless @options[:openstack_tenant]
|
34
|
+
raise 'You must specify an Openstack network (:openstack_network) for OpenStack instances!' unless @options[:openstack_network]
|
35
|
+
@compute_client ||= Fog::Compute.new(:provider => :openstack,
|
36
|
+
:openstack_api_key => @options[:openstack_api_key],
|
37
|
+
:openstack_username => @options[:openstack_username],
|
38
|
+
:openstack_auth_url => @options[:openstack_auth_url],
|
39
|
+
:openstack_tenant => @options[:openstack_tenant])
|
40
|
+
if not @compute_client
|
41
|
+
raise "Unable to create OpenStack Compute instance (api key: #{@options[:openstack_api_key]}, username: #{@options[:openstack_username]}, auth_url: #{@options[:openstack_auth_url]}, tenant: #{@options[:openstack_tenant]})"
|
42
|
+
end
|
43
|
+
@network_client || Fog::Network.new(
|
44
|
+
:provider => :openstack,
|
45
|
+
:openstack_api_key => @options[:openstack_api_key],
|
46
|
+
:openstack_username => @options[:openstack_username],
|
47
|
+
:openstack_auth_url => @options[:openstack_auth_url])
|
48
|
+
if not @network_client
|
49
|
+
|
50
|
+
raise "Unable to create OpenStack Network instance (api_key: #{@options[:openstack_api_key]}, username: #{@options[:openstack_username]}, auth_url: #{@options[:openstack_auth_url]}, tenant: #{@options[:openstack_tenant]})"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
#Provided a flavor name return the OpenStack id for that flavor
|
55
|
+
#@param [String] f The flavor name
|
56
|
+
#@return [String] Openstack id for provided flavor name
|
57
|
+
def flavor f
|
58
|
+
@logger.debug "OpenStack: Looking up flavor '#{f}'"
|
59
|
+
@compute_client.flavors.find { |x| x.name == f } || raise("Couldn't find flavor: #{f}")
|
60
|
+
end
|
61
|
+
|
62
|
+
#Provided an image name return the OpenStack id for that image
|
63
|
+
#@param [String] i The image name
|
64
|
+
#@return [String] Openstack id for provided image name
|
65
|
+
def image i
|
66
|
+
@logger.debug "OpenStack: Looking up image '#{i}'"
|
67
|
+
@compute_client.images.find { |x| x.name == i } || raise("Couldn't find image: #{i}")
|
68
|
+
end
|
69
|
+
|
70
|
+
#Provided a network name return the OpenStack id for that network
|
71
|
+
#@param [String] n The network name
|
72
|
+
#@return [String] Openstack id for provided network name
|
73
|
+
def network n
|
74
|
+
@logger.debug "OpenStack: Looking up network '#{n}'"
|
75
|
+
@network_client.networks.find { |x| x.name == n } || raise("Couldn't find network: #{n}")
|
76
|
+
end
|
77
|
+
|
78
|
+
#Create new instances in OpenStack
|
79
|
+
def provision
|
80
|
+
@logger.notify "Provisioning OpenStack"
|
81
|
+
|
82
|
+
@hosts.each do |host|
|
83
|
+
host[:vmhostname] = generate_host_name
|
84
|
+
@logger.debug "Provisioning #{host.name} (#{host[:vmhostname]})"
|
85
|
+
options = {
|
86
|
+
:flavor_ref => flavor(host[:flavor]).id,
|
87
|
+
:image_ref => image(host[:image]).id,
|
88
|
+
:nics => [ {'net_id' => network(@options[:openstack_network]).id } ],
|
89
|
+
:name => host[:vmhostname],
|
90
|
+
}
|
91
|
+
if @options[:openstack_keyname]
|
92
|
+
@logger.debug "Adding optional key_name #{@options[:openstack_keyname]} to #{host.name} (#{host[:vmhostname]})"
|
93
|
+
options[:key_name] = @options[:openstack_keyname]
|
94
|
+
end
|
95
|
+
vm = @compute_client.servers.create(options)
|
96
|
+
|
97
|
+
#wait for the new instance to start up
|
98
|
+
start = Time.now
|
99
|
+
try = 1
|
100
|
+
attempts = @options[:timeout].to_i / SLEEPWAIT
|
101
|
+
|
102
|
+
while try <= attempts
|
103
|
+
begin
|
104
|
+
vm.wait_for(5) { ready? }
|
105
|
+
break
|
106
|
+
rescue Fog::Errors::TimeoutError => e
|
107
|
+
if try >= attempts
|
108
|
+
@logger.debug "Failed to connect to new OpenStack instance #{host.name} (#{host[:vmhostname]})"
|
109
|
+
raise e
|
110
|
+
end
|
111
|
+
@logger.debug "Timeout connecting to instance #{host.name} (#{host[:vmhostname]}), trying again..."
|
112
|
+
end
|
113
|
+
sleep SLEEPWAIT
|
114
|
+
try += 1
|
115
|
+
end
|
116
|
+
|
117
|
+
# Associate a public IP to the server
|
118
|
+
# Create if there are no floating ips available
|
119
|
+
#
|
120
|
+
ip = @compute_client.addresses.find { |ip| ip.instance_id.nil? }
|
121
|
+
if ip.nil?
|
122
|
+
@logger.debug "Creating IP for #{host.name} (#{host[:vmhostname]})"
|
123
|
+
ip = @compute_client.addresses.create
|
124
|
+
end
|
125
|
+
ip.server = vm
|
126
|
+
host[:ip] = ip.ip
|
127
|
+
@logger.debug "OpenStack host #{host.name} (#{host[:vmhostname]}) assigned ip: #{host[:ip]}"
|
128
|
+
|
129
|
+
#set metadata
|
130
|
+
vm.metadata.update({:jenkins_build_url => @options[:jenkins_build_url].to_s,
|
131
|
+
:department => @options[:department].to_s,
|
132
|
+
:project => @options[:project].to_s })
|
133
|
+
@vms << vm
|
134
|
+
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
#Destroy any OpenStack instances
|
139
|
+
def cleanup
|
140
|
+
@logger.notify "Cleaning up OpenStack"
|
141
|
+
@vms.each do |vm|
|
142
|
+
@logger.debug "Release floating IPs for OpenStack host #{vm.name}"
|
143
|
+
floating_ips = vm.all_addresses # fetch and release its floating IPs
|
144
|
+
floating_ips.each do |address|
|
145
|
+
@compute_client.disassociate_address(vm.id, address['ip'])
|
146
|
+
@compute_client.release_address(address['id'])
|
147
|
+
end
|
148
|
+
@logger.debug "Destroying OpenStack host #{vm.name}"
|
149
|
+
vm.destroy
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
end
|
@@ -119,7 +119,7 @@ module Beaker
|
|
119
119
|
:add_el_extras => false,
|
120
120
|
:release_apt_repo_url => "http://apt.puppetlabs.com",
|
121
121
|
:release_yum_repo_url => "http://yum.puppetlabs.com",
|
122
|
-
:dev_builds_url => "http://builds.puppetlabs.
|
122
|
+
:dev_builds_url => "http://builds.delivery.puppetlabs.net",
|
123
123
|
:consoleport => 443,
|
124
124
|
:pe_dir => '/opt/enterprise/dists',
|
125
125
|
:pe_version_file => 'LATEST',
|
data/lib/beaker/perf.rb
CHANGED
@@ -2,6 +2,11 @@ module Beaker
|
|
2
2
|
# The Beaker Perf class. A single instance is created per Beaker run.
|
3
3
|
class Perf
|
4
4
|
|
5
|
+
PERF_PACKAGES = ['sysstat']
|
6
|
+
# SLES does not treat sysstat as a service that can be started
|
7
|
+
PERF_SUPPORTED_PLATFORMS = /debian|ubuntu|redhat|centos|oracle|scientific|fedora|el|sles/
|
8
|
+
PERF_START_PLATFORMS = /debian|ubuntu|redhat|centos|oracle|scientific|fedora|el/
|
9
|
+
|
5
10
|
# Create the Perf instance and runs setup_perf_on_host on all hosts if --collect-perf-data
|
6
11
|
# was used as an option on the Baker command line invocation. Instances of this class do not
|
7
12
|
# hold state and its methods are helpers for remotely executing tasks for performance data
|
@@ -18,11 +23,22 @@ module Beaker
|
|
18
23
|
@hosts.map { |h| setup_perf_on_host(h) }
|
19
24
|
end
|
20
25
|
|
21
|
-
#
|
26
|
+
# Install sysstat if required and perform any modifications needed to make sysstat work.
|
22
27
|
# @param [Host] host The host we are working with
|
23
28
|
# @return [void]
|
24
29
|
def setup_perf_on_host(host)
|
25
30
|
@logger.perf_output("Setup perf on host: " + host)
|
31
|
+
# Install sysstat if required
|
32
|
+
if host['platform'] =~ PERF_SUPPORTED_PLATFORMS
|
33
|
+
PERF_PACKAGES.each do |pkg|
|
34
|
+
if not host.check_for_package pkg
|
35
|
+
host.install_package pkg
|
36
|
+
end
|
37
|
+
end
|
38
|
+
else
|
39
|
+
@logger.perf_output("Perf (sysstat) not supported on host: " + host)
|
40
|
+
end
|
41
|
+
|
26
42
|
if host['platform'] =~ /debian|ubuntu/
|
27
43
|
@logger.perf_output("Modify /etc/default/sysstat on Debian and Ubuntu platforms")
|
28
44
|
host.exec(Command.new('sed -i s/ENABLED=\"false\"/ENABLED=\"true\"/ /etc/default/sysstat'))
|
@@ -30,7 +46,7 @@ module Beaker
|
|
30
46
|
@logger.perf_output("Creating symlink from /etc/sysstat/sysstat.cron to /etc/cron.d")
|
31
47
|
host.exec(Command.new('ln -s /etc/sysstat/sysstat.cron /etc/cron.d'),:acceptable_exit_codes => [0,1])
|
32
48
|
end
|
33
|
-
if host['platform'] =~
|
49
|
+
if host['platform'] =~ PERF_START_PLATFORMS # SLES doesn't need this step
|
34
50
|
host.exec(Command.new('service sysstat start'))
|
35
51
|
end
|
36
52
|
end
|
@@ -50,8 +66,10 @@ module Beaker
|
|
50
66
|
# @return [void] The report is sent to the logging output
|
51
67
|
def get_perf_data(host, perf_start, perf_end)
|
52
68
|
@logger.perf_output("Getting perf data for host: " + host)
|
53
|
-
if host['platform'] =~
|
54
|
-
host.exec(Command.new("sar -A -s #{perf_start.strftime("%H:%M:%S")} -e #{perf_end.strftime("%H:%M:%S")}"))
|
69
|
+
if host['platform'] =~ PERF_SUPPORTED_PLATFORMS # All flavours of Linux
|
70
|
+
host.exec(Command.new("sar -A -s #{perf_start.strftime("%H:%M:%S")} -e #{perf_end.strftime("%H:%M:%S")}"),:acceptable_exit_codes => [0,1,2])
|
71
|
+
else
|
72
|
+
@logger.perf_output("Perf (sysstat) not supported on host: " + host)
|
55
73
|
end
|
56
74
|
end
|
57
75
|
end
|
@@ -166,7 +166,7 @@ module Beaker
|
|
166
166
|
def scp_to source, target, options = {}, dry_run = false
|
167
167
|
return if dry_run
|
168
168
|
|
169
|
-
options[:recursive] = File.directory?(source)
|
169
|
+
options[:recursive] = File.directory?(source)
|
170
170
|
options[:chunk_size] = options[:chunk_size] || 16384
|
171
171
|
|
172
172
|
result = Result.new(@hostname, [source, target])
|
@@ -188,7 +188,7 @@ module Beaker
|
|
188
188
|
def scp_from source, target, options = {}, dry_run = false
|
189
189
|
return if dry_run
|
190
190
|
|
191
|
-
options[:recursive] = true
|
191
|
+
options[:recursive] = true
|
192
192
|
options[:chunk_size] = options[:chunk_size] || 16384
|
193
193
|
|
194
194
|
result = Result.new(@hostname, [source, target])
|
data/lib/beaker/version.rb
CHANGED
@@ -1232,7 +1232,7 @@ describe ClassMixedWithDSLHelpers do
|
|
1232
1232
|
end
|
1233
1233
|
|
1234
1234
|
describe 'copy_module_to' do
|
1235
|
-
let(:ignore_list){
|
1235
|
+
let(:ignore_list) { Beaker::DSL::Helpers::PUPPET_MODULE_INSTALL_IGNORE }
|
1236
1236
|
let(:source){'./'}
|
1237
1237
|
let(:target){'/etc/puppetlabs/puppet/modules/testmodule'}
|
1238
1238
|
let(:module_parse_name){'testmodule'}
|
@@ -88,6 +88,47 @@ describe ClassMixedWithDSLInstallUtils do
|
|
88
88
|
|
89
89
|
subject.install_from_git( host, path, repo )
|
90
90
|
end
|
91
|
+
|
92
|
+
it 'allows a checkout depth of 1' do
|
93
|
+
repo = { :name => 'puppet',
|
94
|
+
:path => 'git://my.server.net/puppet.git',
|
95
|
+
:rev => 'master',
|
96
|
+
:depth => 1 }
|
97
|
+
|
98
|
+
path = '/path/to/repos'
|
99
|
+
cmd = "test -d #{path}/#{repo[:name]} || git clone --branch #{repo[:rev]} --depth #{repo[:depth]} #{repo[:path]} #{path}/#{repo[:name]}"
|
100
|
+
host = { 'platform' => 'debian' }
|
101
|
+
logger = double.as_null_object
|
102
|
+
subject.should_receive( :logger ).exactly( 3 ).times.and_return( logger )
|
103
|
+
subject.should_receive( :on ).with( host,"test -d #{path} || mkdir -p #{path}").exactly( 1 ).times
|
104
|
+
# this is the the command we want to test
|
105
|
+
subject.should_receive( :on ).with( host, cmd ).exactly( 1 ).times
|
106
|
+
subject.should_receive( :on ).with( host, "cd #{path}/#{repo[:name]} && git remote rm origin && git remote add origin #{repo[:path]} && git fetch origin && git clean -fdx && git checkout -f #{repo[:rev]}" ).exactly( 1 ).times
|
107
|
+
subject.should_receive( :on ).with( host, "cd #{path}/#{repo[:name]} && if [ -f install.rb ]; then ruby ./install.rb ; else true; fi" ).exactly( 1 ).times
|
108
|
+
|
109
|
+
subject.install_from_git( host, path, repo )
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'allows a checkout depth with a rev from a specific branch' do
|
113
|
+
repo = { :name => 'puppet',
|
114
|
+
:path => 'git://my.server.net/puppet.git',
|
115
|
+
:rev => 'a2340acddadfeafd234230faf',
|
116
|
+
:depth => 50,
|
117
|
+
:depth_branch => 'master' }
|
118
|
+
|
119
|
+
path = '/path/to/repos'
|
120
|
+
cmd = "test -d #{path}/#{repo[:name]} || git clone --branch #{repo[:depth_branch]} --depth #{repo[:depth]} #{repo[:path]} #{path}/#{repo[:name]}"
|
121
|
+
host = { 'platform' => 'debian' }
|
122
|
+
logger = double.as_null_object
|
123
|
+
subject.should_receive( :logger ).exactly( 3 ).times.and_return( logger )
|
124
|
+
subject.should_receive( :on ).with( host,"test -d #{path} || mkdir -p #{path}").exactly( 1 ).times
|
125
|
+
# this is the the command we want to test
|
126
|
+
subject.should_receive( :on ).with( host, cmd ).exactly( 1 ).times
|
127
|
+
subject.should_receive( :on ).with( host, "cd #{path}/#{repo[:name]} && git remote rm origin && git remote add origin #{repo[:path]} && git fetch origin && git clean -fdx && git checkout -f #{repo[:rev]}" ).exactly( 1 ).times
|
128
|
+
subject.should_receive( :on ).with( host, "cd #{path}/#{repo[:name]} && if [ -f install.rb ]; then ruby ./install.rb ; else true; fi" ).exactly( 1 ).times
|
129
|
+
|
130
|
+
subject.install_from_git( host, path, repo )
|
131
|
+
end
|
91
132
|
end
|
92
133
|
|
93
134
|
describe 'sorted_hosts' do
|
@@ -105,6 +146,7 @@ describe ClassMixedWithDSLInstallUtils do
|
|
105
146
|
describe 'installer_cmd' do
|
106
147
|
|
107
148
|
it 'generates a windows PE install command for a windows host' do
|
149
|
+
winhost['dist'] = 'puppet-enterprise-3.0'
|
108
150
|
subject.stub( :hosts ).and_return( [ hosts[1], hosts[0], hosts[2], winhost ] )
|
109
151
|
expect( subject.installer_cmd( winhost, {} ) ).to be === "cd /tmp && cmd /C 'start /w msiexec.exe /qn /L*V tmp.log /i puppet-enterprise-3.0.msi PUPPET_MASTER_SERVER=vm1 PUPPET_AGENT_CERTNAME=winhost'"
|
110
152
|
end
|
@@ -210,6 +252,7 @@ describe ClassMixedWithDSLInstallUtils do
|
|
210
252
|
File.stub( :directory? ).and_return( true ) #is local
|
211
253
|
File.stub( :exists? ).and_return( true ) #is present
|
212
254
|
winhost['pe_dir'] = '/local/file/path'
|
255
|
+
winhost['dist'] = 'puppet-enterprise-3.0'
|
213
256
|
subject.stub( :scp_to ).and_return( true )
|
214
257
|
|
215
258
|
path = winhost['pe_dir']
|
@@ -265,6 +308,7 @@ describe ClassMixedWithDSLInstallUtils do
|
|
265
308
|
subject.stub( :sign_certificate_for ).and_return( true )
|
266
309
|
subject.stub( :stop_agent_on ).and_return( true )
|
267
310
|
subject.stub( :sleep_until_puppetdb_started ).and_return( true )
|
311
|
+
subject.stub( :version_is_less ).with('3.0', '3.4').and_return( true )
|
268
312
|
subject.stub( :version_is_less ).with('3.0', '3.0').and_return( false )
|
269
313
|
subject.stub( :wait_for_host_in_dashboard ).and_return( true )
|
270
314
|
subject.stub( :puppet_agent ).and_return do |arg|
|
@@ -436,7 +480,7 @@ describe ClassMixedWithDSLInstallUtils do
|
|
436
480
|
end
|
437
481
|
it 'falls back to installing from gem when given :default_action => "gem_install"' do
|
438
482
|
result = double
|
439
|
-
gem_env_string = '{"RubyGems Environment": [ {"GEM PATHS": [] } ] }'
|
483
|
+
gem_env_string = '{"RubyGems Environment": [ {"GEM PATHS": [], "EXECUTABLE DIRECTORY": "/does/not/exist" } ] }'
|
440
484
|
allow( result ).to receive(:stdout).and_return gem_env_string
|
441
485
|
allow(subject).to receive(:on).with(host, /gem environment/).and_return result
|
442
486
|
expect(subject).to receive(:on).with(host, /gem install/)
|
@@ -278,22 +278,6 @@ describe Beaker do
|
|
278
278
|
|
279
279
|
end
|
280
280
|
|
281
|
-
it "can validate unix hosts that need sysstat installed" do
|
282
|
-
total_pkgs = Array.new(unix_only_pkgs);
|
283
|
-
total_pkgs << "sysstat"
|
284
|
-
|
285
|
-
hosts.each do |host|
|
286
|
-
total_pkgs.each do |pkg|
|
287
|
-
host.should_receive( :check_for_package ).with( pkg ).once.and_return( false )
|
288
|
-
host.should_receive( :install_package ).with( pkg ).once
|
289
|
-
end
|
290
|
-
end
|
291
|
-
|
292
|
-
opts = options.merge({:collect_perf_data => true})
|
293
|
-
subject.validate_host(hosts, opts)
|
294
|
-
|
295
|
-
end
|
296
|
-
|
297
281
|
it "can validate windows hosts" do
|
298
282
|
@platform = 'windows'
|
299
283
|
|
@@ -171,21 +171,25 @@ module Beaker
|
|
171
171
|
end
|
172
172
|
|
173
173
|
it 'should stop the containers' do
|
174
|
+
docker.stub( :sleep ).and_return(true)
|
174
175
|
container.should_receive(:stop)
|
175
176
|
docker.cleanup
|
176
177
|
end
|
177
178
|
|
178
179
|
it 'should delete the containers' do
|
180
|
+
docker.stub( :sleep ).and_return(true)
|
179
181
|
container.should_receive(:delete)
|
180
182
|
docker.cleanup
|
181
183
|
end
|
182
184
|
|
183
185
|
it 'should delete the images' do
|
186
|
+
docker.stub( :sleep ).and_return(true)
|
184
187
|
image.should_receive(:delete)
|
185
188
|
docker.cleanup
|
186
189
|
end
|
187
190
|
|
188
191
|
it 'should not delete the image if docker_preserve_image is set to true' do
|
192
|
+
docker.stub( :sleep ).and_return(true)
|
189
193
|
hosts.each do |host|
|
190
194
|
host['docker_preserve_image']=true
|
191
195
|
end
|
@@ -194,6 +198,7 @@ module Beaker
|
|
194
198
|
end
|
195
199
|
|
196
200
|
it 'should delete the image if docker_preserve_image is set to false' do
|
201
|
+
docker.stub( :sleep ).and_return(true)
|
197
202
|
hosts.each do |host|
|
198
203
|
host['docker_preserve_image']=false
|
199
204
|
end
|
data/spec/beaker/perf_spec.rb
CHANGED
@@ -27,6 +27,7 @@ module Beaker
|
|
27
27
|
|
28
28
|
it 'creates a new Perf object with a single host, :collect_perf_data = true' do
|
29
29
|
hosts = [ make_host("myHost", @options) ]
|
30
|
+
hosts.each { |host| host['platform'] = "centos-6-x86_64" }
|
30
31
|
@my_logger.remove_destination(STDOUT)
|
31
32
|
perf = Perf.new( hosts, @options )
|
32
33
|
expect( perf ).to be_a_kind_of Perf
|
@@ -35,6 +36,7 @@ module Beaker
|
|
35
36
|
|
36
37
|
it 'creates a new Perf object with multiple hosts, :collect_perf_data = true' do
|
37
38
|
hosts = [ make_host("myHost", @options), make_host("myOtherHost", @options) ]
|
39
|
+
hosts.each { |host| host['platform'] = "centos-6-x86_64" }
|
38
40
|
@my_logger.remove_destination(STDOUT)
|
39
41
|
perf = Perf.new( hosts, @options )
|
40
42
|
expect( perf ).to be_a_kind_of Perf
|
@@ -43,7 +45,8 @@ module Beaker
|
|
43
45
|
|
44
46
|
it 'creates a new Perf object with multiple hosts, :collect_perf_data = true, SLES' do
|
45
47
|
hosts = [ make_host("myHost", @options), make_host("myOtherHost", @options) ]
|
46
|
-
hosts[0]['platform'] = "
|
48
|
+
hosts[0]['platform'] = "centos-6-x86_64"
|
49
|
+
hosts[1]['platform'] = "sles-11-x86_64"
|
47
50
|
@my_logger.remove_destination(STDOUT)
|
48
51
|
perf = Perf.new( hosts, @options )
|
49
52
|
expect( perf ).to be_a_kind_of Perf
|
@@ -65,12 +68,12 @@ module Beaker
|
|
65
68
|
end
|
66
69
|
|
67
70
|
it "Does the Right Thing on Linux hosts" do
|
68
|
-
@hosts[0]['platform'] = "centos"
|
71
|
+
@hosts[0]['platform'] = "centos-6-x86_64"
|
69
72
|
@my_logger.remove_destination(STDOUT)
|
70
73
|
perf = Perf.new( @hosts, @options )
|
71
74
|
expect( perf ).to be_a_kind_of Perf
|
72
75
|
perf.print_perf_info
|
73
|
-
expect(@my_io.string).to match(/Setup perf on host: myHostSetup perf on host: myOtherHostGetting perf data for host: myHostGetting perf data for host: myOtherHost/)
|
76
|
+
expect(@my_io.string).to match(/Setup perf on host: myHostSetup perf on host: myOtherHostPerf \(sysstat\) not supported on host: myOtherHostGetting perf data for host: myHostGetting perf data for host: myOtherHostPerf \(sysstat\) not supported on host: myOtherHost/)
|
74
77
|
end
|
75
78
|
|
76
79
|
it "Does the Right Thing on non-Linux hosts" do
|
@@ -79,7 +82,7 @@ module Beaker
|
|
79
82
|
perf = Perf.new( @hosts, @options )
|
80
83
|
expect( perf ).to be_a_kind_of Perf
|
81
84
|
perf.print_perf_info
|
82
|
-
expect(@my_io.string).to match(/Setup perf on host: myHostSetup perf on host: myOtherHostGetting perf data for host: myHostGetting perf data for host: myOtherHost/)
|
85
|
+
expect(@my_io.string).to match(/Setup perf on host: myHostPerf \(sysstat\) not supported on host: myHostSetup perf on host: myOtherHostPerf \(sysstat\) not supported on host: myOtherHostGetting perf data for host: myHostPerf \(sysstat\) not supported on host: myHostGetting perf data for host: myOtherHostPerf \(sysstat\) not supported on host: myOtherHost/)
|
83
86
|
end
|
84
87
|
end
|
85
88
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: beaker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.18.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppetlabs
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-09-
|
11
|
+
date: 2014-09-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -304,6 +304,20 @@ dependencies:
|
|
304
304
|
- - ! '>='
|
305
305
|
- !ruby/object:Gem::Version
|
306
306
|
version: '0'
|
307
|
+
- !ruby/object:Gem::Dependency
|
308
|
+
name: fog
|
309
|
+
requirement: !ruby/object:Gem::Requirement
|
310
|
+
requirements:
|
311
|
+
- - ~>
|
312
|
+
- !ruby/object:Gem::Version
|
313
|
+
version: 1.22.1
|
314
|
+
type: :runtime
|
315
|
+
prerelease: false
|
316
|
+
version_requirements: !ruby/object:Gem::Requirement
|
317
|
+
requirements:
|
318
|
+
- - ~>
|
319
|
+
- !ruby/object:Gem::Version
|
320
|
+
version: 1.22.1
|
307
321
|
- !ruby/object:Gem::Dependency
|
308
322
|
name: nokogiri
|
309
323
|
requirement: !ruby/object:Gem::Requirement
|
@@ -416,6 +430,7 @@ files:
|
|
416
430
|
- lib/beaker/hypervisor/fusion.rb
|
417
431
|
- lib/beaker/hypervisor/google_compute.rb
|
418
432
|
- lib/beaker/hypervisor/google_compute_helper.rb
|
433
|
+
- lib/beaker/hypervisor/openstack.rb
|
419
434
|
- lib/beaker/hypervisor/solaris.rb
|
420
435
|
- lib/beaker/hypervisor/vagrant.rb
|
421
436
|
- lib/beaker/hypervisor/vcloud.rb
|