vagrant-pe_build 0.12.0 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +24 -0
- data/README.markdown +152 -71
- data/acceptance/pe_build/pe_bootstrap_2015x_spec.rb +61 -13
- data/acceptance/pe_build/pe_bootstrap_3x_spec.rb +6 -3
- data/acceptance/pe_build/pe_bootstrap_latest_spec.rb +6 -3
- data/acceptance/skeletons/2015x_acceptance/Vagrantfile +25 -49
- data/acceptance/skeletons/pe_build/Vagrantfile +1 -1
- data/lib/pe_build/cap.rb +9 -0
- data/lib/pe_build/cap/detect_installer/base.rb +18 -0
- data/lib/pe_build/cap/detect_installer/posix.rb +0 -15
- data/lib/pe_build/cap/detect_installer/windows.rb +22 -4
- data/lib/pe_build/cap/facts/base.rb +119 -0
- data/lib/pe_build/cap/facts/debian.rb +37 -0
- data/lib/pe_build/cap/facts/posix.rb +36 -0
- data/lib/pe_build/cap/facts/redhat.rb +37 -0
- data/lib/pe_build/cap/facts/solaris.rb +46 -0
- data/lib/pe_build/cap/facts/suse.rb +38 -0
- data/lib/pe_build/cap/facts/ubuntu.rb +35 -0
- data/lib/pe_build/cap/facts/windows.rb +58 -0
- data/lib/pe_build/command.rb +1 -0
- data/lib/pe_build/command/base.rb +2 -1
- data/lib/pe_build/command/facts.rb +63 -0
- data/lib/pe_build/config.rb +1 -0
- data/lib/pe_build/config/pe_agent.rb +120 -0
- data/lib/pe_build/config_builder.rb +1 -0
- data/lib/pe_build/config_builder/pe_agent.rb +44 -0
- data/lib/pe_build/plugin.rb +44 -0
- data/lib/pe_build/provisioner/pe_agent.rb +262 -0
- data/lib/pe_build/release.rb +1 -1
- data/lib/pe_build/release/2015_2.rb +1 -0
- data/lib/pe_build/util/machine_comms.rb +51 -0
- data/lib/pe_build/util/pe_packaging.rb +57 -0
- data/lib/pe_build/version.rb +1 -1
- data/spec/unit/config/pe_agent_spec.rb +154 -0
- data/spec/unit/provisioner/pe_agent_spec.rb +101 -0
- data/tasks/acceptance.rake +2 -1
- data/templates/locales/en.yml +53 -0
- data/vagrant-pe_build.gemspec +4 -4
- data/vagrant-spec.config.example.rb +1 -1
- metadata +24 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47561a70a1c02283bba9c70a97e051730f204fc4
|
4
|
+
data.tar.gz: 996f48ec7088af25312fecf60f7a1f841d541080
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9acee36342d28520e8fbc2266b7b1bfdc74bb8c52f59cb9ffcf5c11614a584c8ed1e34b0d077fd05d56e4253ebdc38e19a9c487e01f5bbe70804e8754c1900d6
|
7
|
+
data.tar.gz: d7c96302dc35a03ad6c08b7e63a62814c29c6338a161df39e73dcf3eedda49b4afc9feacc2c8f1585c4bbcf356755c61c4cf4d773b04421bc3626be76ebf1a2a
|
data/CHANGELOG
CHANGED
@@ -1,6 +1,30 @@
|
|
1
1
|
vagrant-pe_build
|
2
2
|
================
|
3
3
|
|
4
|
+
0.13.0
|
5
|
+
------
|
6
|
+
|
7
|
+
2015-10-18
|
8
|
+
|
9
|
+
This is a backwards compatible feature release.
|
10
|
+
|
11
|
+
* Support for PE 2015.2.2.
|
12
|
+
|
13
|
+
* (GH-69), (GH-54) Added a new `pe_agent` provisioner which provides
|
14
|
+
fictionless agent installation for PE 2015.2.0 and newer. This provisioner
|
15
|
+
also supports orchestrating actions on the PE master VM, such as setting
|
16
|
+
up `pe_repo` to serve agent packages, signing agent certificates and
|
17
|
+
purging agent data when VMs are destroyed.
|
18
|
+
|
19
|
+
* (GH-99) Windows agents running PE 3.7.0 and newer are now installed from
|
20
|
+
64-bit packages if the underlying hardware supports it.
|
21
|
+
|
22
|
+
* (GH-91) New guest capability for retrieving VM facts using `puppet facts`.
|
23
|
+
A basic set of `architecture`, `os` and `release` facts is provided if
|
24
|
+
Puppet is not installed. There is a new command, `puppet pe-build facts`
|
25
|
+
for retrieving this data in JSON format, but the primary usecase is to
|
26
|
+
inform `pe_agent` decision-making.
|
27
|
+
|
4
28
|
0.12.0
|
5
29
|
------
|
6
30
|
|
data/README.markdown
CHANGED
@@ -14,7 +14,7 @@ on Vagrant boxes to rapidly build a functioning Puppet environment.
|
|
14
14
|
Vagrantfile Settings
|
15
15
|
-------------------
|
16
16
|
|
17
|
-
|
17
|
+
### Global `config.pe_build` Settings
|
18
18
|
|
19
19
|
These settings go in the config object namespace and act as defaults in
|
20
20
|
the event multiple machines are being provisioned. These settings are
|
@@ -42,11 +42,11 @@ optional and can be overridden in a VM's individual provisioner config.
|
|
42
42
|
* file
|
43
43
|
* A blank URI will default to `file`.
|
44
44
|
|
45
|
-
|
45
|
+
### `pe_bootstrap` Provisioner Settings
|
46
46
|
|
47
47
|
These settings are on a per provisioner basis. They configure the individual
|
48
|
-
behaviors of
|
49
|
-
overridden at this point.
|
48
|
+
behaviors of each provisioner instance. All of the `config.pe_build` options
|
49
|
+
can be overridden at this point.
|
50
50
|
|
51
51
|
* `role`
|
52
52
|
* Description: The role of the Puppet Enterprise install.
|
@@ -78,113 +78,194 @@ overridden at this point.
|
|
78
78
|
* Options: `true`, `false`
|
79
79
|
* Default: `false`
|
80
80
|
|
81
|
+
### `pe_agent` Provisioner Settings
|
82
|
+
|
83
|
+
The `pe_agent` provisioner installs the Puppet Agent for PE 2015.2.0 and above
|
84
|
+
and, optionally, configures PE Master VMs to support the new agent.
|
85
|
+
|
86
|
+
|
87
|
+
**NOTE:** The `pe_agent` provisioner currently does not share any configuration
|
88
|
+
with the global `config.pe_build` settings.
|
89
|
+
|
90
|
+
* `master_vm`
|
91
|
+
* Description: The name of a VM in the current Vagrant environment which
|
92
|
+
hosts the Puppet master that the agent should be connected to. When this
|
93
|
+
is set, the `master`, `autosign` and `autopurge` settings are populated
|
94
|
+
with default values. If the `master_vm` setting is not used, then the
|
95
|
+
`master` setting _must_ be populated with the hostname of the
|
96
|
+
Puppet Master.
|
97
|
+
* Default: `nil`.
|
98
|
+
* `autosign`
|
99
|
+
* Description: An boolean switch which controls whether or not to sign the
|
100
|
+
agent's certificate after installation. Requires `master_vm` to be set.
|
101
|
+
* Options: `true`, `false`
|
102
|
+
* Default: `true`, if `master_vm` is set.
|
103
|
+
* `autopurge`
|
104
|
+
* Description: An boolean switch which controls whether or not to clean the
|
105
|
+
agent's certificate from the master and purge agent data from PuppetDB
|
106
|
+
when the agent VM is destroyed. Requires `master_vm` to be set.
|
107
|
+
* Options: `true`, `false`
|
108
|
+
* Default: `true`, if `master_vm` is set.
|
109
|
+
* `master`
|
110
|
+
* Description: The hostname or fqdn of the puppet master. Must be specified
|
111
|
+
if `master_vm` is not set.
|
112
|
+
* Default: `nil`. Defaults to `vm.hostname` of the Puppet Master if
|
113
|
+
`master_vm` is set.
|
114
|
+
* `version`
|
115
|
+
* Description: The version number of the PE Agent to install. **NOTE:**
|
116
|
+
this setting is currently used only for Windows agents. POSIX agents will
|
117
|
+
always receive the `'current'` version installed on the master. Support
|
118
|
+
for setting the version number of POSIX agents will be added in a future
|
119
|
+
release.
|
120
|
+
* Options: A version string, `x.y.z[-optional-stuff]`, or the string
|
121
|
+
`'current'`.
|
122
|
+
* Default: `'current'`.
|
123
|
+
|
124
|
+
|
81
125
|
Commands
|
82
126
|
--------
|
83
127
|
|
84
128
|
Usage Example
|
85
129
|
-------------
|
86
130
|
|
87
|
-
### Minimal configuration
|
131
|
+
### Minimal PE 3.x configuration
|
88
132
|
|
89
133
|
This requires that the necessary installers have already been downloaded and
|
90
134
|
added with `vagrant pe-build copy`.
|
91
135
|
|
92
|
-
|
93
|
-
|
136
|
+
```ruby
|
137
|
+
Vagrant.configure('2') do |config|
|
138
|
+
config.pe_build.version = '3.8.2'
|
139
|
+
|
140
|
+
config.vm.define 'master' do |node|
|
141
|
+
node.vm.box = 'puppetlabs/centos-7.0-64-nocm'
|
142
|
+
|
143
|
+
node.vm.provision :pe_bootstrap do |p|
|
144
|
+
p.role = :master
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
config.vm.define 'agent1' do |node|
|
149
|
+
node.vm.box = 'puppetlabs/centos-7.0-64-nocm'
|
150
|
+
node.vm.provision :pe_bootstrap
|
151
|
+
end
|
152
|
+
end
|
153
|
+
```
|
154
|
+
|
94
155
|
|
95
|
-
|
96
|
-
node.vm.box = 'centos-6-i386'
|
156
|
+
### Minimal PE 2015.x configuration
|
97
157
|
|
98
|
-
|
99
|
-
|
100
|
-
end
|
101
|
-
end
|
158
|
+
Same as above, but uses `pe_agent` to provision agent nodes instead
|
159
|
+
of `pe_bootstrap`.
|
102
160
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
161
|
+
```ruby
|
162
|
+
Vagrant.configure('2') do |config|
|
163
|
+
config.pe_build.version = '2015.2.2'
|
164
|
+
|
165
|
+
config.vm.define 'master' do |node|
|
166
|
+
node.vm.box = 'puppetlabs/centos-7.0-64-nocm'
|
167
|
+
|
168
|
+
node.vm.provision :pe_bootstrap do |p|
|
169
|
+
p.role = :master
|
108
170
|
end
|
171
|
+
end
|
109
172
|
|
110
|
-
|
173
|
+
config.vm.define 'agent1' do |node|
|
174
|
+
node.vm.box = 'puppetlabs/centos-7.0-64-nocm'
|
175
|
+
node.vm.provision :pe_agent do |p|
|
176
|
+
p.master_vm = 'master'
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
```
|
111
181
|
|
112
|
-
Vagrant.configure('2') do |config|
|
113
|
-
config.pe_build.version = '3.0.0'
|
114
|
-
config.pe_build.download_root = 'http://my.pe.download.mirror/installers'
|
115
182
|
|
116
|
-
|
117
|
-
#config.pe_build.download_root = 'file://Users/luke/Downloads'
|
183
|
+
### Specifying a download root
|
118
184
|
|
119
|
-
|
120
|
-
|
185
|
+
```ruby
|
186
|
+
Vagrant.configure('2') do |config|
|
187
|
+
config.pe_build.version = '3.8.2'
|
188
|
+
config.pe_build.download_root = 'http://my.pe.download.mirror/installers'
|
121
189
|
|
122
|
-
|
123
|
-
|
124
|
-
end
|
125
|
-
end
|
190
|
+
# Alternately, a local directory can be specified
|
191
|
+
#config.pe_build.download_root = 'file://Users/luke/Downloads'
|
126
192
|
|
127
|
-
|
128
|
-
|
193
|
+
config.vm.define 'master' do |node|
|
194
|
+
node.vm.box = 'puppetlabs/centos-7.0-64-nocm'
|
129
195
|
|
130
|
-
|
131
|
-
|
196
|
+
node.vm.provision :pe_bootstrap do |p|
|
197
|
+
p.role = :master
|
132
198
|
end
|
199
|
+
end
|
133
200
|
|
134
|
-
|
201
|
+
config.vm.define 'agent1' do |node|
|
202
|
+
node.vm.box = 'puppetlabs/centos-7.0-64-nocm'
|
203
|
+
|
204
|
+
node.vm.provision :pe_bootstrap
|
205
|
+
end
|
206
|
+
end
|
207
|
+
```
|
135
208
|
|
136
|
-
Vagrant.configure('2') do |config|
|
137
|
-
config.pe_build.version = '3.0.0'
|
138
|
-
config.pe_build.download_root = 'http://my.pe.download.mirror/installers'
|
139
209
|
|
140
|
-
|
141
|
-
#config.pe_build.download_root = 'file://Users/luke/Downloads'
|
210
|
+
### Using a manual answers file
|
142
211
|
|
143
|
-
|
144
|
-
|
212
|
+
```ruby
|
213
|
+
Vagrant.configure('2') do |config|
|
214
|
+
config.pe_build.version = '3.8.2'
|
215
|
+
config.pe_build.download_root = 'http://my.pe.download.mirror/installers'
|
145
216
|
|
146
|
-
|
147
|
-
|
148
|
-
provisioner.answer_file = 'answers/vagrant_master.answers.txt'
|
149
|
-
end
|
150
|
-
end
|
217
|
+
# Alternately, a local directory can be specified
|
218
|
+
#config.pe_build.download_root = 'file://Users/luke/Downloads'
|
151
219
|
|
152
|
-
|
153
|
-
|
220
|
+
config.vm.define 'master' do |node|
|
221
|
+
node.vm.box = 'puppetlabs/centos-7.0-64-nocm'
|
154
222
|
|
155
|
-
|
156
|
-
|
223
|
+
node.vm.provision :pe_bootstrap do |p|
|
224
|
+
p.role = :master
|
225
|
+
p.answer_file = 'answers/vagrant_master.answers.txt'
|
157
226
|
end
|
227
|
+
end
|
158
228
|
|
159
|
-
|
229
|
+
config.vm.define 'agent1' do |node|
|
230
|
+
node.vm.box = 'puppetlabs/centos-7.0-64-nocm'
|
160
231
|
|
161
|
-
|
162
|
-
|
163
|
-
|
232
|
+
node.vm.provision :pe_bootstrap
|
233
|
+
end
|
234
|
+
end
|
235
|
+
```
|
164
236
|
|
165
|
-
# Alternately, a local directory can be specified
|
166
|
-
#config.pe_build.download_root = 'file://Users/luke/Downloads'
|
167
237
|
|
168
|
-
|
169
|
-
|
238
|
+
### Manually setting a filename
|
239
|
+
|
240
|
+
```ruby
|
241
|
+
Vagrant.configure('2') do |config|
|
242
|
+
config.pe_build.version = '3.8.2'
|
243
|
+
config.pe_build.filename = 'puppet-enterprise-3.8.2-el-7-x86_64.tar.gz'
|
170
244
|
|
171
|
-
|
172
|
-
|
173
|
-
provisioner.answer_file = 'answers/vagrant_master.answers.txt'
|
174
|
-
end
|
175
|
-
end
|
245
|
+
# Alternately, a local directory can be specified
|
246
|
+
#config.pe_build.download_root = 'file://Users/luke/Downloads'
|
176
247
|
|
177
|
-
|
178
|
-
|
248
|
+
config.vm.define 'master' do |node|
|
249
|
+
node.vm.box = 'puppetlabs/centos-7.0-64-nocm'
|
179
250
|
|
180
|
-
|
181
|
-
|
251
|
+
node.vm.provision :pe_bootstrap do |p|
|
252
|
+
p.role = :master
|
182
253
|
end
|
254
|
+
end
|
255
|
+
|
256
|
+
config.vm.define 'agent1' do |node|
|
257
|
+
node.vm.box = 'puppetlabs/centos-7.0-64-nocm'
|
258
|
+
|
259
|
+
node.vm.provision :pe_bootstrap
|
260
|
+
end
|
261
|
+
end
|
262
|
+
```
|
263
|
+
|
183
264
|
|
184
265
|
Requirements
|
185
266
|
------------
|
186
267
|
|
187
|
-
[vagranthosts]: https://github.com/
|
268
|
+
[vagranthosts]: https://github.com/oscar-stack/vagrant-hosts
|
188
269
|
|
189
270
|
Ensure VMs have a FQDN set before installing PE. The easiest way to do this is by setting the `hostname` attribute of the VM configuration.
|
190
271
|
|
@@ -198,8 +279,8 @@ they have private network interfaces prepared.
|
|
198
279
|
Contact
|
199
280
|
-------
|
200
281
|
|
201
|
-
* [Source code](https://github.com/
|
202
|
-
* [Issue tracker](https://github.com/
|
282
|
+
* [Source code](https://github.com/oscar-stack/vagrant-pe_build)
|
283
|
+
* [Issue tracker](https://github.com/oscar-stack/vagrant-pe_build/issues)
|
203
284
|
|
204
285
|
If you have questions or concerns about this module, contact finch on on
|
205
286
|
Freenode, or email adrien@puppetlabs.com.
|
@@ -1,7 +1,7 @@
|
|
1
1
|
shared_examples 'provider/provisioner/pe_bootstrap/2015x' do |provider, options|
|
2
|
-
if
|
2
|
+
if options[:boxes].empty?
|
3
3
|
raise ArgumentError,
|
4
|
-
"
|
4
|
+
"Box files must be downloaded for provider: #{provider}. Try: rake acceptance:setup"
|
5
5
|
end
|
6
6
|
|
7
7
|
include_context 'acceptance'
|
@@ -17,7 +17,10 @@ shared_examples 'provider/provisioner/pe_bootstrap/2015x' do |provider, options|
|
|
17
17
|
# The skelton sets up a Vagrantfile which expects the OS under test to be
|
18
18
|
# available as `box`.
|
19
19
|
environment.skeleton('2015x_acceptance')
|
20
|
-
|
20
|
+
options[:boxes].each do |box|
|
21
|
+
name = File.basename(box).split('-').first
|
22
|
+
assert_execute('vagrant', 'box', 'add', name, box)
|
23
|
+
end
|
21
24
|
end
|
22
25
|
|
23
26
|
after(:each) do
|
@@ -25,21 +28,66 @@ shared_examples 'provider/provisioner/pe_bootstrap/2015x' do |provider, options|
|
|
25
28
|
assert_execute('vagrant', 'destroy', '--force', log: false)
|
26
29
|
end
|
27
30
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
31
|
+
# TODO: Refactor into a shared example so tha this testcase can be run on
|
32
|
+
# multiple versions.
|
33
|
+
context 'when installing PE 2015.2.x' do
|
34
|
+
it 'provisions masters with pe_bootstrap and agents with pe_agent' do
|
35
|
+
status('Test: pe_bootstrap master install')
|
36
|
+
assert_execute('vagrant', 'up', "--provider=#{provider}", 'pe-20152-master')
|
37
|
+
|
38
|
+
status('Test: pe_bootstrap master running after install')
|
39
|
+
result = execute('vagrant', 'ssh',
|
40
|
+
'pe-20152-master',
|
41
|
+
'-c', 'sudo /opt/puppetlabs/bin/puppet status --terminus=rest')
|
42
|
+
expect(result).to exit_with(0)
|
43
|
+
expect(result.stdout).to match('"is_alive": true')
|
44
|
+
|
45
|
+
status('Test: pe_agent install')
|
46
|
+
result = assert_execute('vagrant', 'up', "--provider=#{provider}", 'pe-20152-agent')
|
47
|
+
|
48
|
+
status('Test: pe_agent signed cert during install')
|
49
|
+
result = execute('vagrant', 'ssh',
|
50
|
+
'pe-20152-master',
|
51
|
+
'-c', 'sudo /opt/puppetlabs/bin/puppet cert list pe-20152-agent.pe-bootstrap.vlan')
|
52
|
+
expect(result).to exit_with(0)
|
33
53
|
|
34
|
-
|
35
|
-
|
36
|
-
|
54
|
+
status('Test: pe_agent cert purged when vm destroyed')
|
55
|
+
result = assert_execute('vagrant', 'destroy', '-f', 'pe-20152-agent')
|
56
|
+
result = execute('vagrant', 'ssh',
|
57
|
+
'pe-20152-master',
|
58
|
+
'-c', 'sudo /opt/puppetlabs/bin/puppet cert list pe-20152-agent.pe-bootstrap.vlan')
|
59
|
+
expect(result.stderr).to match(/Could not find a certificate/)
|
37
60
|
end
|
38
61
|
end
|
39
62
|
|
40
63
|
context 'when installing PE 2015.latest' do
|
41
|
-
it 'provisions with
|
42
|
-
|
64
|
+
it 'provisions masters with pe_bootstrap and agents with pe_agent' do
|
65
|
+
status('Test: pe_bootstrap master install')
|
66
|
+
assert_execute('vagrant', 'up', "--provider=#{provider}", 'pe-2015latest-master')
|
67
|
+
|
68
|
+
status('Test: pe_bootstrap master running after install')
|
69
|
+
result = execute('vagrant', 'ssh',
|
70
|
+
'pe-2015latest-master',
|
71
|
+
'-c', 'sudo /opt/puppetlabs/bin/puppet status --terminus=rest')
|
72
|
+
expect(result).to exit_with(0)
|
73
|
+
expect(result.stdout).to match('"is_alive": true')
|
74
|
+
|
75
|
+
status('Test: pe_agent install')
|
76
|
+
result = assert_execute('vagrant', 'up', "--provider=#{provider}", 'pe-2015latest-agent')
|
77
|
+
|
78
|
+
status('Test: pe_agent signed cert during install')
|
79
|
+
result = execute('vagrant', 'ssh',
|
80
|
+
'pe-2015latest-master',
|
81
|
+
'-c', 'sudo /opt/puppetlabs/bin/puppet cert list pe-2015latest-agent.pe-bootstrap.vlan')
|
82
|
+
expect(result).to exit_with(0)
|
83
|
+
|
84
|
+
status('Test: pe_agent cert purged when vm destroyed')
|
85
|
+
result = assert_execute('vagrant', 'destroy', '-f', 'pe-2015latest-agent')
|
86
|
+
result = execute('vagrant', 'ssh',
|
87
|
+
'pe-2015latest-master',
|
88
|
+
'-c', 'sudo /opt/puppetlabs/bin/puppet cert list pe-2015latest-agent.pe-bootstrap.vlan')
|
89
|
+
expect(result.stderr).to match(/Could not find a certificate/)
|
43
90
|
end
|
44
91
|
end
|
92
|
+
|
45
93
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
shared_examples 'provider/provisioner/pe_bootstrap/3x' do |provider, options|
|
2
|
-
if
|
2
|
+
if options[:boxes].empty?
|
3
3
|
raise ArgumentError,
|
4
|
-
"
|
4
|
+
"Box files must be downloaded for provider: #{provider}. Try: rake acceptance:setup"
|
5
5
|
end
|
6
6
|
|
7
7
|
include_context 'acceptance'
|
@@ -17,7 +17,10 @@ shared_examples 'provider/provisioner/pe_bootstrap/3x' do |provider, options|
|
|
17
17
|
# The skelton sets up a Vagrantfile which expects the OS under test to be
|
18
18
|
# available as `box`.
|
19
19
|
environment.skeleton('pe_build')
|
20
|
-
|
20
|
+
options[:boxes].each do |box|
|
21
|
+
name = File.basename(box).split('-').first
|
22
|
+
assert_execute('vagrant', 'box', 'add', name, box)
|
23
|
+
end
|
21
24
|
end
|
22
25
|
|
23
26
|
after(:each) do
|