onceover 3.8.0 → 3.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -9
- data/README.md +8 -123
- data/factsets/windows-10-64.json +103 -0
- data/features/run.feature +5 -0
- data/features/step_definitions/common.rb +9 -5
- data/lib/onceover/cli/run.rb +2 -0
- data/lib/onceover/controlrepo.rb +6 -0
- data/lib/onceover/deploy.rb +152 -0
- data/lib/onceover/runner.rb +0 -3
- data/lib/onceover/testconfig.rb +0 -145
- data/onceover.gemspec +1 -1
- data/spec/fixtures/controlrepos/caching/spec/onceover.yaml +3 -2
- data/spec/fixtures/controlrepos/function_mocking/spec/onceover.yaml +1 -1
- data/templates/controlrepo.yaml.erb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a37e753c95878c5de3f89a71d73e97b835e3ee54
|
4
|
+
data.tar.gz: 5a71d30c65ef86e645110719ef752ad6306c99bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 61c0d522ccd4864f4bb224a6a60560f8c3852eb2037472d727b73b768132665bf137277248e59bac088ddedcb3eac421af30598e8830db619df9473ee3e69c5d
|
7
|
+
data.tar.gz: 56b657a2e74bb3344cb88785024afd4e977d74a04dbd1690c33e497157a2fe6c993b4b720e8c01c1347116e8e8d7e20856157bc9c9c9481241428c09bd4af697
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
*The gateway drug to automated infrastructure testing with Puppet*
|
4
4
|
|
5
|
-
Onceover is a tool to automatically run basic tests on an entire Puppet controlrepo. It includes automatic parsing the `Puppetfile`, `environment.conf` and others in order to run
|
5
|
+
Onceover is a tool to automatically run basic tests on an entire Puppet controlrepo. It includes automatic parsing of the `Puppetfile`, `environment.conf` and others in order to run stop silly mistakes ever reaching your Puppet Master!
|
6
6
|
|
7
7
|
## Table of Contents
|
8
8
|
|
@@ -12,11 +12,9 @@ Onceover is a tool to automatically run basic tests on an entire Puppet controlr
|
|
12
12
|
- [Config files](#config-files)
|
13
13
|
- [onceover.yaml](#onceoveryaml)
|
14
14
|
- [factsets](#factsets)
|
15
|
-
- [nodesets](#nodesets)
|
16
15
|
- [Hiera Data](#hiera-data)
|
17
16
|
- [Spec testing](#spec-testing)
|
18
17
|
- [Adding your own spec tests](#adding-your-own-spec-tests)
|
19
|
-
- [Acceptance testing](#acceptance-testing)
|
20
18
|
- [Using Workarounds](#using-workarounds)
|
21
19
|
- [Extra tooling](#extra-tooling)
|
22
20
|
- [Plugins](#plugins)
|
@@ -66,7 +64,7 @@ Run your spec tests!
|
|
66
64
|
|
67
65
|
## Overview
|
68
66
|
|
69
|
-
This gem provides a toolset for testing Puppet Controlrepos (Repos used with r10k). The main purpose of this project is to provide a set of tools to help smooth out the process of setting up and running
|
67
|
+
This gem provides a toolset for testing Puppet Controlrepos (Repos used with r10k). The main purpose of this project is to provide a set of tools to help smooth out the process of setting up and running rspec-puppet tests for a controlrepo. Due to the fact that controlrepos are fairly standardised in nature it seemed ridiculous that you would need to set up the same testing framework that we would normally use within a module for a controlrepo. This is because at this level we are normally just running very basic tests that cover a lot of code. It would also mean that we would need to essentially duplicated our `Puppetfile` into a `.fixtures.yml` file, along with a few other things.
|
70
68
|
|
71
69
|
This toolset requires some config before it can be used so definitely read that section before getting started.
|
72
70
|
|
@@ -82,17 +80,15 @@ This project uses one main config file to determine what classes we should be te
|
|
82
80
|
|
83
81
|
If we are doing spec testing we need sets of facts to compile the puppet code against, these are stored in [factsets](#factsets). (A few are provided out of the box for you)
|
84
82
|
|
85
|
-
If we are doing acceptance testing then we need information about how to spin up VMs to do the testing on, these are configured in [nodesets](#nodesets). (Once again these are auto-generated with `onceover init`)
|
86
|
-
|
87
83
|
### onceover.yaml
|
88
84
|
|
89
85
|
`spec/onceover.yaml` _(override with environment variable: `ONCEOVER_YAML`)_
|
90
86
|
|
91
|
-
Hopefully this config file will be fairly self explanatory once you see it, but basically this is the place where we define what classes we want to test and the [factsets](#factsets)
|
87
|
+
Hopefully this config file will be fairly self explanatory once you see it, but basically this is the place where we define what classes we want to test and the [factsets](#factsets) that we want to test them against. The config file must contain the following sections:
|
92
88
|
|
93
89
|
**classes:** A list (array) of classes that we want to test, usually this would be your roles, possibly profiles if you want. (If you don't know what roles and profiles are please [READ THIS](http://garylarizza.com/blog/2014/02/17/puppet-workflow-part-2/)). To make life easier you can also specify one or many **regular expressions** in this section. A good one to start with would be `/^role::/`. Regular expressions are just strings that start and end with a forward slash.
|
94
90
|
|
95
|
-
**nodes:** The nodes that we want to test against. The nodes that we list here map directly to
|
91
|
+
**nodes:** The nodes that we want to test against. The nodes that we list here map directly to a [factset](#factsets).
|
96
92
|
|
97
93
|
**node_groups:** The `node_groups` section is just for saving us some typing. Here we can set up groups of nodes which we can then refer to in our test matrix. We can create groups by simply specifying an array of servers to be in the group, or we can use the subtractive *include/exclude* syntax. The names used for the actual `class_groups` and `node_groups` must be unique.
|
98
94
|
|
@@ -103,7 +99,7 @@ Hopefully this config file will be fairly self explanatory once you see it, but
|
|
103
99
|
```yaml
|
104
100
|
- {nodes_to_test}: # The name of a node or node group
|
105
101
|
classes: '{classes_to_test}' # the name of a class or
|
106
|
-
tests: '{all_tests|acceptance|spec}' #
|
102
|
+
tests: '{all_tests|acceptance|spec}' # acceptance deprecated/broken, set to spec
|
107
103
|
{valid_option}: {value} # Check the doco for available options
|
108
104
|
```
|
109
105
|
|
@@ -190,10 +186,10 @@ test_matrix:
|
|
190
186
|
classes: 'non_windows_roles'
|
191
187
|
- ubuntu_servers:
|
192
188
|
classes: 'all_classes'
|
193
|
-
tests: '
|
189
|
+
tests: 'spec'
|
194
190
|
- centos_severs:
|
195
191
|
classes: 'roles::frontend_webserver'
|
196
|
-
tests: '
|
192
|
+
tests: 'spec'
|
197
193
|
runs_before_idempotency: 2
|
198
194
|
tags:
|
199
195
|
- 'frontend'
|
@@ -224,14 +220,6 @@ It's important to note that in order to reference a group using the *include/exc
|
|
224
220
|
|
225
221
|
#### Optional test parameters
|
226
222
|
|
227
|
-
**check_idempotency** *Default: true*
|
228
|
-
|
229
|
-
Weather or not to check that puppet will be idempotent (Acceptance testing only)
|
230
|
-
|
231
|
-
**runs_before_idempotency** *Default: 1*
|
232
|
-
|
233
|
-
The number of runs to try before checking that it is idempotent. Required for some things that require restarts of the server or restarts of puppet. (Acceptance testing only)
|
234
|
-
|
235
223
|
**tags** *Default: nil*
|
236
224
|
|
237
225
|
One or many tags that tests in this group should be tagged with. This allows you to run only certain tests using the `--tags` command line parameter. **NOTE:** Custom spec tests will always be run as they are not subject to tags
|
@@ -258,7 +246,7 @@ Would map to a node named `server2008r2` in `onceover.yaml`
|
|
258
246
|
|
259
247
|
#### Trusted Facts
|
260
248
|
|
261
|
-
You can add trusted facts to the
|
249
|
+
You can add trusted facts to the factsets by creating a new section called trusted:
|
262
250
|
|
263
251
|
```
|
264
252
|
{
|
@@ -276,69 +264,6 @@ You can add trusted facts to the nodesets by creating a new section called trust
|
|
276
264
|
|
277
265
|
Notice that the `extensions` part is implied. The first fact in that example translates to `$trusted['extensions']['pp_role']` in Puppet code.
|
278
266
|
|
279
|
-
### nodesets
|
280
|
-
|
281
|
-
`spec/acceptance/nodesets/onceover-nodes.yml`
|
282
|
-
|
283
|
-
Nodesets are used when running acceptance tests. They instruct the onceover gem how to spin up virtual machines to run the code on. Actually, that's a lie... What's really happening with nodesets is that we are using [Beaker](https://github.com/puppetlabs/beaker) to spin up the machines and then a combination of Beaker and RSpec to test them. But you don't need to worry about that too much. Due to the fact that we are using beaker to do the heavy lifting here the nodeset files follow the same format they would for normal Beaker tests, which at the time of writing supports the following hypervisors:
|
284
|
-
|
285
|
-
- [VMWare Fusion](https://github.com/puppetlabs/beaker/blob/master/docs/VMWare-Fusion-Support.md)
|
286
|
-
- [Amazon EC2](https://github.com/puppetlabs/beaker/blob/master/docs/EC2-Support.md)
|
287
|
-
- [vSphere](https://github.com/puppetlabs/beaker/blob/master/docs/vSphere-Support.md)
|
288
|
-
- [Vagrant](https://github.com/puppetlabs/beaker/blob/master/docs/Vagrant-Support.md)
|
289
|
-
- [Google Compute Engine](https://github.com/puppetlabs/beaker/blob/master/docs/Google-Compute-Engine-Support.md)
|
290
|
-
- [Docker](https://github.com/puppetlabs/beaker/blob/master/docs/Docker-Support.md)
|
291
|
-
- [Openstack](https://github.com/puppetlabs/beaker/blob/master/docs/Openstack-Support.md)
|
292
|
-
- [Solaris](https://github.com/puppetlabs/beaker/blob/master/docs/Solaris-Support.md)
|
293
|
-
|
294
|
-
Before we configure a hypervisor to spin up a node however, we have to make sure that it can clone from a machine which is ready. The onceover gem **requires it's VMs to have puppet pre-installed.** It doesn't matter what version of puppet, as long as it is on the PATH and the `type` setting is configured correctly i.e.
|
295
|
-
|
296
|
-
```yaml
|
297
|
-
type: AIO # For machines that have the all-in-one agent installed (>=4.0 or >=2015.2)
|
298
|
-
# OR
|
299
|
-
type: pe # For puppet enterprise agents <2015.2
|
300
|
-
# OR
|
301
|
-
type: foss # For open source puppet <4.0
|
302
|
-
```
|
303
|
-
|
304
|
-
Here is an example of a nodeset file that you can use yourselves. It uses freely available Vagrant boxes from Puppet and Virtualbox as the Vagrant provider. (`onceover init` will generate most of this for you)
|
305
|
-
|
306
|
-
```yaml
|
307
|
-
HOSTS:
|
308
|
-
centos6a:
|
309
|
-
roles:
|
310
|
-
- agent
|
311
|
-
type: aio
|
312
|
-
platform: el-6-64
|
313
|
-
box: puppetlabs/centos-6.6-64-puppet
|
314
|
-
box_url: https://atlas.hashicorp.com/puppetlabs/boxes/centos-6.6-64-puppet
|
315
|
-
hypervisor: vagrant_virtualbox
|
316
|
-
centos7b:
|
317
|
-
roles:
|
318
|
-
- agent
|
319
|
-
type: aio
|
320
|
-
platform: el-7-64
|
321
|
-
box: puppetlabs/centos-7.0-64-puppet
|
322
|
-
box_url: https://atlas.hashicorp.com/puppetlabs/boxes/centos-7.0-64-puppet
|
323
|
-
hypervisor: vagrant_virtualbox
|
324
|
-
ubuntu1204:
|
325
|
-
roles:
|
326
|
-
- agent
|
327
|
-
type: aio
|
328
|
-
platform: ubuntu-12.04-32
|
329
|
-
box: puppetlabs/ubuntu-12.04-32-puppet
|
330
|
-
box_url: https://atlas.hashicorp.com/puppetlabs/boxes/ubuntu-12.04-32-puppet
|
331
|
-
hypervisor: vagrant_virtualbox
|
332
|
-
debian78:
|
333
|
-
roles:
|
334
|
-
- agent
|
335
|
-
type: aio
|
336
|
-
platform: debian-7.8-64
|
337
|
-
box: puppetlabs/debian-7.8-64-puppet
|
338
|
-
box_url: https://atlas.hashicorp.com/puppetlabs/boxes/debian-7.8-64-puppet
|
339
|
-
hypervisor: vagrant_virtualbox
|
340
|
-
```
|
341
|
-
|
342
267
|
### Hiera Data
|
343
268
|
|
344
269
|
If you have hiera data inside your controlrepo (or somewhere else) Onceover can be configured to use it. It is however worth noting the the `hiera.yaml` file that you currently use may not be applicable for testing right away. For example; if you are using `hiera-eyaml` I recommend creating a `hiera.yaml` purely for testing that simply uses the `yaml` backend, meaning that you don't need to provide the private keys to the testing machines.
|
@@ -405,26 +330,6 @@ If you want to see Puppet's output, you can set the `SHOW_PUPPET_OUTPUT` environ
|
|
405
330
|
|
406
331
|
`SHOW_PUPPET_OUTPUT=true onceover run spec`
|
407
332
|
|
408
|
-
## Acceptance testing
|
409
|
-
|
410
|
-
Acceptance testing works in much the same way as spec testing except that it requires a nodeset file along with `onceover.yaml`
|
411
|
-
|
412
|
-
To run the tests:
|
413
|
-
|
414
|
-
`onceover run acceptance`
|
415
|
-
|
416
|
-
This will do the following things:
|
417
|
-
|
418
|
-
1. Create a temporary directory under `.onceover`
|
419
|
-
2. Clone all repos in the Puppetfile into the temporary directory
|
420
|
-
3. Generate tests that use RSpec and Beaker
|
421
|
-
4. Run the tests, each test consists of:
|
422
|
-
- Spin up the VM
|
423
|
-
- Copy over the code
|
424
|
-
- Run puppet and catch any errors
|
425
|
-
- Run puppet again to catch anything that might not be idempotent
|
426
|
-
- Destroy the VM
|
427
|
-
|
428
333
|
## Using workarounds
|
429
334
|
|
430
335
|
There may be situations where you cannot test everything that is in your puppet code, some common reasons for this include:
|
@@ -480,29 +385,9 @@ or
|
|
480
385
|
}
|
481
386
|
```
|
482
387
|
|
483
|
-
However this is going to pose an issue when we get to acceptance testing. Due to the fact that acceptance tests actually run the code, not just tries to compile a catalog, it will not be able to find the 'pe-pupetserver' service and will fail. One way to get around this is to use some of the optional parameters to the service resource e.g.
|
484
|
-
|
485
|
-
```puppet
|
486
|
-
# We are not going to actually have this service anywhere on our servers but
|
487
|
-
# our code needs to refresh it. This is to trick puppet into doing nothing
|
488
|
-
service { 'pe-puppetserver':
|
489
|
-
ensure => 'running',
|
490
|
-
enable => false,
|
491
|
-
hasrestart => false, # Force Puppet to use start and stop to restart
|
492
|
-
start => 'echo "Start"', # This will always exit 0
|
493
|
-
stop => 'echo "Stop"', # This will also always exit 0
|
494
|
-
hasstatus => false, # Force puppet to use our command for status
|
495
|
-
status => 'echo "Status"', # This will always exit 0 and therefore Puppet will think the service is running
|
496
|
-
provider => 'base',
|
497
|
-
}
|
498
|
-
```
|
499
|
-
|
500
|
-
Here we are specifying custom commands to run for starting, stopping and checking the status of a service. We know what the exit codes of these commands are going to be so we know what puppet will think the service is doing because we have [read the documentation](https://docs.puppetlabs.com/references/latest/type.html#service-attributes). If there are things other than services you need to check then I would recommend checking the documentation to see if you can mock things like we have here. Alternatively you might need to create specific VM images that are pre-prepared.
|
501
388
|
|
502
389
|
[Resource collectors](https://docs.puppetlabs.com/puppet/latest/reference/lang_resources_advanced.html#amending-attributes-with-a-collector) are likely to come in handy here too. They allow you to override values of resources that match given criteria. This way we can override things for the sake of testing without having to change the code.
|
503
390
|
|
504
|
-
**NOTE:** If you need to run some pre_conditions during acceptance tests but not spec tests or vice versa you can check the status of the `$controlrepo_accpetance` variable. It will be `true` when run as an acceptance test and `undef` otherwise. If you want to limit pre_conditions to only certain nodes just use conditional logic based on facts like you normally would.
|
505
|
-
|
506
391
|
**NOTE:** If you want to access the class or factset that onceover is running against just use the `$onceover_class` and `$onceover_node` variables respectively.
|
507
392
|
|
508
393
|
## Extra Tooling
|
@@ -0,0 +1,103 @@
|
|
1
|
+
{
|
2
|
+
"name": "vagrant-hb9g3rd.lan.asio",
|
3
|
+
"values": {
|
4
|
+
"puppetversion": "6.0.2",
|
5
|
+
"puppet_inventory_metadata": {
|
6
|
+
"packages": {
|
7
|
+
"collection_enabled": false,
|
8
|
+
"last_collection_time": "0.0s"
|
9
|
+
}
|
10
|
+
},
|
11
|
+
"package_provider": "windows",
|
12
|
+
"pe_concat_basedir": "C:/ProgramData/PuppetLabs/puppet/cache/pe_concat",
|
13
|
+
"is_pe": false,
|
14
|
+
"platform_symlink_writable": false,
|
15
|
+
"puppet_files_dir_present": false,
|
16
|
+
"puppet_vardir": "C:/ProgramData/PuppetLabs/puppet/cache",
|
17
|
+
"puppet_environmentpath": "C:/ProgramData/PuppetLabs/code/environments",
|
18
|
+
"puppet_server": "pe-puppet.localdomain",
|
19
|
+
"service_provider": "windows",
|
20
|
+
"staging_http_get": "curl",
|
21
|
+
"common_appdata": "C:\\ProgramData",
|
22
|
+
"architecture": "x64",
|
23
|
+
"kernel": "windows",
|
24
|
+
"virtual": "vmware",
|
25
|
+
"is_virtual": true,
|
26
|
+
"hardwaremodel": "x64",
|
27
|
+
"operatingsystem": "windows",
|
28
|
+
"os": {
|
29
|
+
"name": "windows",
|
30
|
+
"family": "windows",
|
31
|
+
"release": {
|
32
|
+
"major": "10",
|
33
|
+
"full": "10"
|
34
|
+
}
|
35
|
+
},
|
36
|
+
"facterversion": "2.5.1",
|
37
|
+
"fqdn": "VAGRANT-HB9G3RD",
|
38
|
+
"hostname": "VAGRANT-HB9G3RD",
|
39
|
+
"id": "vagrant-hb9g3rd\\vagrant",
|
40
|
+
"interfaces": "Ethernet0_2",
|
41
|
+
"ipaddress_ethernet0_2": "192.168.43.174",
|
42
|
+
"ipaddress6_ethernet0_2": "fd72:b3ab:b8dd:0:f563:fac2:928c:6aa",
|
43
|
+
"macaddress_ethernet0_2": "00:0C:29:A3:53:54",
|
44
|
+
"netmask_ethernet0_2": "255.255.255.0",
|
45
|
+
"mtu_ethernet0_2": 0,
|
46
|
+
"ipaddress": "192.168.43.174",
|
47
|
+
"ipaddress6": "fd72:b3ab:b8dd:0:f563:fac2:928c:6aa",
|
48
|
+
"kernelmajversion": "10.0",
|
49
|
+
"kernelrelease": "10.0.17134",
|
50
|
+
"kernelversion": "10.0.17134",
|
51
|
+
"macaddress": "00:0C:29:A3:53:54",
|
52
|
+
"manufacturer": "Phoenix Technologies LTD",
|
53
|
+
"serialnumber": "VMware-56 4d 36 2e 2e a4 81 f9-0d 05 ae d0 e5 a3 53 54",
|
54
|
+
"productname": "VMware Virtual Platform",
|
55
|
+
"memorysize": "4.00 GB",
|
56
|
+
"memoryfree": "2.30 GB",
|
57
|
+
"memorysize_mb": "4095.49",
|
58
|
+
"memoryfree_mb": "2360.00",
|
59
|
+
"netmask": "255.255.255.0",
|
60
|
+
"network_ethernet0_2": "192.168.43.0",
|
61
|
+
"operatingsystemmajrelease": "10",
|
62
|
+
"operatingsystemrelease": "10",
|
63
|
+
"osfamily": "windows",
|
64
|
+
"path": "C:\\tools\\ruby24\\bin;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Windows\\System32\\OpenSSH\\;C:\\ProgramData\\chocolatey\\bin;C:\\Program Files (x86)\\vim\\vim80;C:\\Program Files\\Git\\cmd;C:\\Program Files\\Puppet Labs\\Puppet\\bin;C:\\Users\\vagrant\\AppData\\Local\\Microsoft\\WindowsApps;",
|
65
|
+
"physicalprocessorcount": 4,
|
66
|
+
"processors": {
|
67
|
+
"models": [
|
68
|
+
"Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz",
|
69
|
+
"Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz",
|
70
|
+
"Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz",
|
71
|
+
"Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz"
|
72
|
+
],
|
73
|
+
"count": 4,
|
74
|
+
"physicalcount": 4
|
75
|
+
},
|
76
|
+
"processor0": "Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz",
|
77
|
+
"processor1": "Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz",
|
78
|
+
"processor2": "Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz",
|
79
|
+
"processor3": "Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz",
|
80
|
+
"processorcount": 4,
|
81
|
+
"ps": "tasklist.exe",
|
82
|
+
"rubyplatform": "x64-mingw32",
|
83
|
+
"rubysitedir": "C:/tools/ruby24/lib/ruby/site_ruby/2.4.0",
|
84
|
+
"rubyversion": "2.4.3",
|
85
|
+
"system32": "C:\\Windows\\system32",
|
86
|
+
"system_uptime": {
|
87
|
+
"seconds": 1113359,
|
88
|
+
"hours": 309,
|
89
|
+
"days": 12,
|
90
|
+
"uptime": "12 days"
|
91
|
+
},
|
92
|
+
"timezone": "GMT Standard Time",
|
93
|
+
"uptime": "12 days",
|
94
|
+
"uptime_days": 12,
|
95
|
+
"uptime_hours": 309,
|
96
|
+
"uptime_seconds": 1113359,
|
97
|
+
"clientcert": "vagrant-hb9g3rd.lan.asio",
|
98
|
+
"clientversion": "6.0.2",
|
99
|
+
"clientnoop": false
|
100
|
+
},
|
101
|
+
"timestamp": "2018-12-10T21:43:07.468533000+00:00",
|
102
|
+
"expiration": "2018-12-10T22:13:07.468533000+00:00"
|
103
|
+
}
|
data/features/run.feature
CHANGED
@@ -12,6 +12,11 @@ Feature: Run rspec and acceptance test suites
|
|
12
12
|
When I run onceover command "run spec"
|
13
13
|
Then I should not see any errors
|
14
14
|
|
15
|
+
Scenario: Using regexes to define tests
|
16
|
+
Given initialized control repo "caching"
|
17
|
+
When I run onceover command "run spec"
|
18
|
+
Then I should see message pattern "apache::params"
|
19
|
+
|
15
20
|
Scenario: Run spec tests with misspelled module in Puppetfile
|
16
21
|
Given initialized control repo "basic"
|
17
22
|
And in Puppetfile is misspelled module's name
|
@@ -51,9 +51,13 @@ Then(/^I should see error with message pattern "([^"]*)"$/) do |err_msg_regexp|
|
|
51
51
|
expect(@cmd.output.match err_msg_regexp).to_not be nil
|
52
52
|
end
|
53
53
|
|
54
|
-
Then(/^I should see message pattern "([^"]*)"$/) do |
|
55
|
-
|
56
|
-
|
57
|
-
expect(@cmd.output).to match(
|
58
|
-
|
54
|
+
Then(/^I should see message pattern "([^"]*)"$/) do |msg_regexp|
|
55
|
+
output_surround = 30
|
56
|
+
match = Regexp.new(msg_regexp).match(@cmd.output)
|
57
|
+
expect(@cmd.output).to match(msg_regexp)
|
58
|
+
if match
|
59
|
+
puts match.pre_match[-output_surround..-1] + match.to_s + match.post_match[0..output_surround]
|
60
|
+
else
|
61
|
+
puts @cmd.output
|
62
|
+
end
|
59
63
|
end
|
data/lib/onceover/cli/run.rb
CHANGED
@@ -4,6 +4,7 @@ require 'onceover/cli'
|
|
4
4
|
require 'onceover/runner'
|
5
5
|
require 'onceover/testconfig'
|
6
6
|
require 'onceover/logger'
|
7
|
+
require 'onceover/deploy'
|
7
8
|
|
8
9
|
class Onceover
|
9
10
|
class CLI
|
@@ -43,6 +44,7 @@ This includes deploying using r10k and running all custom tests.
|
|
43
44
|
|
44
45
|
run do |opts, args, cmd|
|
45
46
|
repo = Onceover::Controlrepo.new(opts)
|
47
|
+
Onceover::Deploy.new.deploy_local(repo, opts)
|
46
48
|
runner = Onceover::Runner.new(repo,Onceover::TestConfig.new(repo.onceover_yaml, opts), :spec)
|
47
49
|
runner.prepare!
|
48
50
|
runner.run_spec!
|
data/lib/onceover/controlrepo.rb
CHANGED
@@ -156,11 +156,17 @@ class Onceover
|
|
156
156
|
end
|
157
157
|
|
158
158
|
def classes
|
159
|
+
logger.debug('scanning for classes specified in onceover.yaml')
|
160
|
+
|
159
161
|
# Get all of the possible places for puppet code and look for classes
|
160
162
|
code_dirs = self.config['modulepath']
|
161
163
|
# Remove interpolated references
|
162
164
|
code_dirs.delete_if { |dir| dir[0] == '$'}
|
163
165
|
|
166
|
+
# Include all r10k-downloaded modules to support vendored and/or separate
|
167
|
+
# role and profile classes
|
168
|
+
code_dirs << "#{@tempdir}/#{@environmentpath}/production/modules"
|
169
|
+
|
164
170
|
# Make sure that the paths are relative to the controlrepo root
|
165
171
|
code_dirs.map! do |dir|
|
166
172
|
File.expand_path(dir, @root)
|
@@ -0,0 +1,152 @@
|
|
1
|
+
# handle local deployments (run r10k in .onceover dir)
|
2
|
+
class Onceover
|
3
|
+
class Deploy
|
4
|
+
def deploy_local(repo = Onceover::Controlrepo.new, opts = {})
|
5
|
+
require 'onceover/controlrepo'
|
6
|
+
require 'pathname'
|
7
|
+
|
8
|
+
logger.debug 'Deploying locally (R10K)...'
|
9
|
+
|
10
|
+
skip_r10k = opts[:skip_r10k] || false
|
11
|
+
force = opts[:force] || false
|
12
|
+
|
13
|
+
if repo.tempdir == nil
|
14
|
+
repo.tempdir = Dir.mktmpdir('r10k')
|
15
|
+
else
|
16
|
+
logger.debug "Creating #{repo.tempdir}"
|
17
|
+
FileUtils.mkdir_p(repo.tempdir)
|
18
|
+
end
|
19
|
+
|
20
|
+
# We need to do the copy to a tempdir then move the tempdir to the
|
21
|
+
# destination, just in case we get a recursive copy
|
22
|
+
# TODO: Improve this to save I/O
|
23
|
+
|
24
|
+
# We might need to exclude some files
|
25
|
+
#
|
26
|
+
# if we are using bundler to install gems below the controlrepo
|
27
|
+
# we don't want two copies so exclude those
|
28
|
+
#
|
29
|
+
# If there are more situations like this we can add them to this array as
|
30
|
+
# full paths
|
31
|
+
excluded_dirs = []
|
32
|
+
excluded_dirs << Pathname.new("#{repo.root}/.onceover")
|
33
|
+
excluded_dirs << Pathname.new(ENV['GEM_HOME']) if ENV['GEM_HOME']
|
34
|
+
|
35
|
+
#
|
36
|
+
# A Local modules directory likely means that the user installed r10k folders into their local control repo
|
37
|
+
# This conflicts with the step where onceover installs r10k after copying the control repo to the temporary
|
38
|
+
# .onceover directory. The following skips copying the modules folder, to not later cause an error.
|
39
|
+
#
|
40
|
+
if File.directory?("#{repo.root}/modules")
|
41
|
+
logger.warn "Found modules directory in your controlrepo, skipping the copy of this directory. If you installed modules locally using r10k, this warning is normal, if you have created modules in a local modules directory, onceover does not support testing these files, please rename this directory to conform with Puppet best practices, as this folder will conflict with Puppet's native installation of modules."
|
42
|
+
end
|
43
|
+
excluded_dirs << Pathname.new("#{repo.root}/modules")
|
44
|
+
|
45
|
+
controlrepo_files = get_children_recursive(Pathname.new(repo.root))
|
46
|
+
|
47
|
+
# Exclude the files that should be skipped
|
48
|
+
controlrepo_files.delete_if do |path|
|
49
|
+
parents = [path]
|
50
|
+
path.ascend do |parent|
|
51
|
+
parents << parent
|
52
|
+
end
|
53
|
+
parents.any? { |x| excluded_dirs.include?(x) }
|
54
|
+
end
|
55
|
+
|
56
|
+
folders_to_copy = controlrepo_files.select { |x| x.directory? }
|
57
|
+
files_to_copy = controlrepo_files.select { |x| x.file? }
|
58
|
+
|
59
|
+
logger.debug "Creating temp dir as a staging directory for copying the controlrepo to #{repo.tempdir}"
|
60
|
+
temp_controlrepo = Dir.mktmpdir('controlrepo')
|
61
|
+
|
62
|
+
logger.debug "Creating directories under #{temp_controlrepo}"
|
63
|
+
FileUtils.mkdir_p(folders_to_copy.map { |folder| "#{temp_controlrepo}/#{(folder.relative_path_from(Pathname(repo.root))).to_s}"})
|
64
|
+
|
65
|
+
logger.debug "Copying files to #{temp_controlrepo}"
|
66
|
+
files_to_copy.each do |file|
|
67
|
+
FileUtils.cp(file,"#{temp_controlrepo}/#{(file.relative_path_from(Pathname(repo.root))).to_s}")
|
68
|
+
end
|
69
|
+
|
70
|
+
logger.debug "Writing manifest of copied controlrepo files"
|
71
|
+
require 'json'
|
72
|
+
# Create a manifest of all files that were in the original repo
|
73
|
+
manifest = controlrepo_files.map do |file|
|
74
|
+
# Make sure the paths are relative so they remain relevant when used later
|
75
|
+
file.relative_path_from(Pathname(repo.root)).to_s
|
76
|
+
end
|
77
|
+
# Write all but the first as this is the root and we don't care about that
|
78
|
+
File.write("#{temp_controlrepo}/.onceover_manifest.json",manifest[1..-1].to_json)
|
79
|
+
|
80
|
+
# When using puppetfile vs deploy with r10k, we want to respect the :control_branch
|
81
|
+
# located in the Puppetfile. To accomplish that, we use git and find the current
|
82
|
+
# branch name, then replace strings within the staged puppetfile, prior to copying.
|
83
|
+
|
84
|
+
logger.debug "Checking current working branch"
|
85
|
+
git_branch = `git rev-parse --abbrev-ref HEAD`.chomp
|
86
|
+
|
87
|
+
logger.debug "found #{git_branch} as current working branch"
|
88
|
+
puppetfile_contents = File.read("#{temp_controlrepo}/Puppetfile")
|
89
|
+
|
90
|
+
logger.debug "replacing :control_branch mentions in the Puppetfile with #{git_branch}"
|
91
|
+
new_puppetfile_contents = puppetfile_contents.gsub(/:control_branch/, "'#{git_branch}'")
|
92
|
+
File.write("#{temp_controlrepo}/Puppetfile", new_puppetfile_contents)
|
93
|
+
|
94
|
+
# Remove all files written by the laste onceover run, but not the ones
|
95
|
+
# added by r10k, because that's what we are trying to cache but we don't
|
96
|
+
# know what they are
|
97
|
+
old_manifest_path = "#{repo.tempdir}/#{repo.environmentpath}/production/.onceover_manifest.json"
|
98
|
+
if File.exist? old_manifest_path
|
99
|
+
logger.debug "Found manifest from previous run, parsing..."
|
100
|
+
old_manifest = JSON.parse(File.read(old_manifest_path))
|
101
|
+
logger.debug "Removing #{old_manifest.count} files"
|
102
|
+
old_manifest.reverse.each do |file|
|
103
|
+
FileUtils.rm_f(File.join("#{repo.tempdir}/#{repo.environmentpath}/production/",file))
|
104
|
+
end
|
105
|
+
end
|
106
|
+
FileUtils.mkdir_p("#{repo.tempdir}/#{repo.environmentpath}")
|
107
|
+
|
108
|
+
logger.debug "Copying #{temp_controlrepo} to #{repo.tempdir}/#{repo.environmentpath}/production"
|
109
|
+
FileUtils.cp_r("#{temp_controlrepo}/.", "#{repo.tempdir}/#{repo.environmentpath}/production")
|
110
|
+
FileUtils.rm_rf(temp_controlrepo)
|
111
|
+
|
112
|
+
# Pull the trigger! If it's not already been pulled
|
113
|
+
if repo.tempdir and not skip_r10k
|
114
|
+
if File.directory?(repo.tempdir)
|
115
|
+
# TODO: Change this to call out to r10k directly to do this
|
116
|
+
# Probably something like:
|
117
|
+
# R10K::Settings.global_settings.evaluate(with_overrides)
|
118
|
+
# R10K::Action::Deploy::Environment
|
119
|
+
prod_dir = "#{repo.tempdir}/#{repo.environmentpath}/production"
|
120
|
+
Dir.chdir(prod_dir) do
|
121
|
+
install_cmd = []
|
122
|
+
install_cmd << "r10k puppetfile install --verbose --color --puppetfile #{repo.puppetfile}"
|
123
|
+
install_cmd << "--force" if force
|
124
|
+
install_cmd = install_cmd.join(' ')
|
125
|
+
logger.debug "Running #{install_cmd} from #{prod_dir}"
|
126
|
+
system(install_cmd)
|
127
|
+
raise 'r10k could not install all required modules' unless $?.success?
|
128
|
+
end
|
129
|
+
else
|
130
|
+
raise "#{repo.tempdir} is not a directory"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# Return repo.tempdir for use
|
135
|
+
repo.tempdir
|
136
|
+
end
|
137
|
+
|
138
|
+
private
|
139
|
+
|
140
|
+
def get_children_recursive(pathname)
|
141
|
+
results = []
|
142
|
+
results << pathname
|
143
|
+
pathname.each_child do |child|
|
144
|
+
results << child
|
145
|
+
if child.directory?
|
146
|
+
results << get_children_recursive(child)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
results.flatten
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
data/lib/onceover/runner.rb
CHANGED
@@ -11,9 +11,6 @@ class Onceover
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def prepare!
|
14
|
-
# Deploy the control repo
|
15
|
-
@config.deploy_local(@repo, {:skip_r10k => @config.skip_r10k})
|
16
|
-
|
17
14
|
# Remove the entire spec directory to make sure we have
|
18
15
|
# all the latest tests
|
19
16
|
FileUtils.rm_rf("#{@repo.tempdir}/spec")
|
data/lib/onceover/testconfig.rb
CHANGED
@@ -167,137 +167,6 @@ class Onceover
|
|
167
167
|
puppetcode.join("\n")
|
168
168
|
end
|
169
169
|
|
170
|
-
def deploy_local(repo = Onceover::Controlrepo.new, opts = {})
|
171
|
-
require 'onceover/controlrepo'
|
172
|
-
require 'pathname'
|
173
|
-
|
174
|
-
skip_r10k = opts[:skip_r10k] || false
|
175
|
-
|
176
|
-
if repo.tempdir == nil
|
177
|
-
repo.tempdir = Dir.mktmpdir('r10k')
|
178
|
-
else
|
179
|
-
logger.debug "Creating #{repo.tempdir}"
|
180
|
-
FileUtils.mkdir_p(repo.tempdir)
|
181
|
-
end
|
182
|
-
|
183
|
-
# We need to do the copy to a tempdir then move the tempdir to the
|
184
|
-
# destination, just in case we get a recursive copy
|
185
|
-
# TODO: Improve this to save I/O
|
186
|
-
|
187
|
-
# We might need to exclude some files
|
188
|
-
#
|
189
|
-
# if we are using bundler to install gems below the controlrepo
|
190
|
-
# we don't want two copies so exclude those
|
191
|
-
#
|
192
|
-
# If there are more situations like this we can add them to this array as
|
193
|
-
# full paths
|
194
|
-
excluded_dirs = []
|
195
|
-
excluded_dirs << Pathname.new("#{repo.root}/.onceover")
|
196
|
-
excluded_dirs << Pathname.new(ENV['GEM_HOME']) if ENV['GEM_HOME']
|
197
|
-
|
198
|
-
#
|
199
|
-
# A Local modules directory likely means that the user installed r10k folders into their local control repo
|
200
|
-
# This conflicts with the step where onceover installs r10k after copying the control repo to the temporary
|
201
|
-
# .onceover directory. The following skips copying the modules folder, to not later cause an error.
|
202
|
-
#
|
203
|
-
if File.directory?("#{repo.root}/modules")
|
204
|
-
logger.warn "Found modules directory in your controlrepo, skipping the copy of this directory. If you installed modules locally using r10k, this warning is normal, if you have created modules in a local modules directory, onceover does not support testing these files, please rename this directory to conform with Puppet best practices, as this folder will conflict with Puppet's native installation of modules."
|
205
|
-
end
|
206
|
-
excluded_dirs << Pathname.new("#{repo.root}/modules")
|
207
|
-
|
208
|
-
controlrepo_files = get_children_recursive(Pathname.new(repo.root))
|
209
|
-
|
210
|
-
# Exclude the files that should be skipped
|
211
|
-
controlrepo_files.delete_if do |path|
|
212
|
-
parents = [path]
|
213
|
-
path.ascend do |parent|
|
214
|
-
parents << parent
|
215
|
-
end
|
216
|
-
parents.any? { |x| excluded_dirs.include?(x) }
|
217
|
-
end
|
218
|
-
|
219
|
-
folders_to_copy = controlrepo_files.select { |x| x.directory? }
|
220
|
-
files_to_copy = controlrepo_files.select { |x| x.file? }
|
221
|
-
|
222
|
-
logger.debug "Creating temp dir as a staging directory for copying the controlrepo to #{repo.tempdir}"
|
223
|
-
temp_controlrepo = Dir.mktmpdir('controlrepo')
|
224
|
-
|
225
|
-
logger.debug "Creating directories under #{temp_controlrepo}"
|
226
|
-
FileUtils.mkdir_p(folders_to_copy.map { |folder| "#{temp_controlrepo}/#{(folder.relative_path_from(Pathname(repo.root))).to_s}"})
|
227
|
-
|
228
|
-
logger.debug "Copying files to #{temp_controlrepo}"
|
229
|
-
files_to_copy.each do |file|
|
230
|
-
FileUtils.cp(file,"#{temp_controlrepo}/#{(file.relative_path_from(Pathname(repo.root))).to_s}")
|
231
|
-
end
|
232
|
-
|
233
|
-
logger.debug "Writing manifest of copied controlrepo files"
|
234
|
-
require 'json'
|
235
|
-
# Create a manifest of all files that were in the original repo
|
236
|
-
manifest = controlrepo_files.map do |file|
|
237
|
-
# Make sure the paths are relative so they remain relevant when used later
|
238
|
-
file.relative_path_from(Pathname(repo.root)).to_s
|
239
|
-
end
|
240
|
-
# Write all but the first as this is the root and we don't care about that
|
241
|
-
File.write("#{temp_controlrepo}/.onceover_manifest.json",manifest[1..-1].to_json)
|
242
|
-
|
243
|
-
# When using puppetfile vs deploy with r10k, we want to respect the :control_branch
|
244
|
-
# located in the Puppetfile. To accomplish that, we use git and find the current
|
245
|
-
# branch name, then replace strings within the staged puppetfile, prior to copying.
|
246
|
-
|
247
|
-
logger.debug "Checking current working branch"
|
248
|
-
git_branch = `git rev-parse --abbrev-ref HEAD`.chomp
|
249
|
-
|
250
|
-
logger.debug "found #{git_branch} as current working branch"
|
251
|
-
puppetfile_contents = File.read("#{temp_controlrepo}/Puppetfile")
|
252
|
-
|
253
|
-
logger.debug "replacing :control_branch mentions in the Puppetfile with #{git_branch}"
|
254
|
-
new_puppetfile_contents = puppetfile_contents.gsub(/:control_branch/, "'#{git_branch}'")
|
255
|
-
File.write("#{temp_controlrepo}/Puppetfile", new_puppetfile_contents)
|
256
|
-
|
257
|
-
# Remove all files written by the laste onceover run, but not the ones
|
258
|
-
# added by r10k, because that's what we are trying to cache but we don't
|
259
|
-
# know what they are
|
260
|
-
old_manifest_path = "#{repo.tempdir}/#{repo.environmentpath}/production/.onceover_manifest.json"
|
261
|
-
if File.exist? old_manifest_path
|
262
|
-
logger.debug "Found manifest from previous run, parsing..."
|
263
|
-
old_manifest = JSON.parse(File.read(old_manifest_path))
|
264
|
-
logger.debug "Removing #{old_manifest.count} files"
|
265
|
-
old_manifest.reverse.each do |file|
|
266
|
-
FileUtils.rm_f(File.join("#{repo.tempdir}/#{repo.environmentpath}/production/",file))
|
267
|
-
end
|
268
|
-
end
|
269
|
-
FileUtils.mkdir_p("#{repo.tempdir}/#{repo.environmentpath}")
|
270
|
-
|
271
|
-
logger.debug "Copying #{temp_controlrepo} to #{repo.tempdir}/#{repo.environmentpath}/production"
|
272
|
-
FileUtils.cp_r("#{temp_controlrepo}/.", "#{repo.tempdir}/#{repo.environmentpath}/production")
|
273
|
-
FileUtils.rm_rf(temp_controlrepo)
|
274
|
-
|
275
|
-
# Pull the trigger! If it's not already been pulled
|
276
|
-
if repo.tempdir and not skip_r10k
|
277
|
-
if File.directory?(repo.tempdir)
|
278
|
-
# TODO: Change this to call out to r10k directly to do this
|
279
|
-
# Probably something like:
|
280
|
-
# R10K::Settings.global_settings.evaluate(with_overrides)
|
281
|
-
# R10K::Action::Deploy::Environment
|
282
|
-
prod_dir = "#{repo.tempdir}/#{repo.environmentpath}/production"
|
283
|
-
Dir.chdir(prod_dir) do
|
284
|
-
install_cmd = []
|
285
|
-
install_cmd << "r10k puppetfile install --verbose --color --puppetfile #{repo.puppetfile}"
|
286
|
-
install_cmd << "--force" if @force
|
287
|
-
install_cmd = install_cmd.join(' ')
|
288
|
-
logger.debug "Running #{install_cmd} from #{prod_dir}"
|
289
|
-
system(install_cmd)
|
290
|
-
raise 'r10k could not install all required modules' unless $?.success?
|
291
|
-
end
|
292
|
-
else
|
293
|
-
raise "#{repo.tempdir} is not a directory"
|
294
|
-
end
|
295
|
-
end
|
296
|
-
|
297
|
-
# Return repo.tempdir for use
|
298
|
-
repo.tempdir
|
299
|
-
end
|
300
|
-
|
301
170
|
def write_spec_test(location, test)
|
302
171
|
# Use an ERB template to write a spec test
|
303
172
|
File.write("#{location}/#{test.to_s}_spec.rb",
|
@@ -394,19 +263,5 @@ class Onceover
|
|
394
263
|
end
|
395
264
|
tests
|
396
265
|
end
|
397
|
-
|
398
|
-
private
|
399
|
-
|
400
|
-
def get_children_recursive(pathname)
|
401
|
-
results = []
|
402
|
-
results << pathname
|
403
|
-
pathname.each_child do |child|
|
404
|
-
results << child
|
405
|
-
if child.directory?
|
406
|
-
results << get_children_recursive(child)
|
407
|
-
end
|
408
|
-
end
|
409
|
-
results.flatten
|
410
|
-
end
|
411
266
|
end
|
412
267
|
end
|
data/onceover.gemspec
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = "onceover"
|
7
|
-
s.version = "3.
|
7
|
+
s.version = "3.9.0"
|
8
8
|
s.authors = ["Dylan Ratcliffe"]
|
9
9
|
s.email = ["dylan.ratcliffe@puppet.com"]
|
10
10
|
s.homepage = "https://github.com/dylanratcliffe/onceover"
|
@@ -3,9 +3,10 @@ classes:
|
|
3
3
|
- role::database_server
|
4
4
|
- role::webserver
|
5
5
|
- role::example
|
6
|
+
- /apache::params/
|
6
7
|
|
7
8
|
# Nodes to tests classes on, this refers to a 'factset' or 'nodeset'
|
8
|
-
# depending on
|
9
|
+
# depending on whether you are running 'spec' or 'acceptance' tests
|
9
10
|
nodes:
|
10
11
|
- AIX-7.1-powerpc
|
11
12
|
- SLES-12.1-64
|
@@ -50,4 +51,4 @@ test_matrix:
|
|
50
51
|
tests: 'spec'
|
51
52
|
- non_windows_nodes:
|
52
53
|
classes: 'all_classes'
|
53
|
-
tests: 'acceptance'
|
54
|
+
tests: 'acceptance'
|
@@ -3,7 +3,7 @@ classes:
|
|
3
3
|
- role::test_functions
|
4
4
|
|
5
5
|
# Nodes to tests classes on, this refers to a 'factset' or 'nodeset'
|
6
|
-
# depending on
|
6
|
+
# depending on whether you are running 'spec' or 'acceptance' tests
|
7
7
|
nodes:
|
8
8
|
- CentOS-7.0-64
|
9
9
|
|
@@ -5,7 +5,7 @@ classes:
|
|
5
5
|
<% end -%>
|
6
6
|
|
7
7
|
# Nodes to tests classes on, this refers to a 'factset' or 'nodeset'
|
8
|
-
# depending on
|
8
|
+
# depending on whether you are running 'spec' or 'acceptance' tests
|
9
9
|
nodes:
|
10
10
|
<% repo.facts_files.each do |file| -%>
|
11
11
|
- <%= File.basename(file,'.json') %>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: onceover
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dylan Ratcliffe
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-12-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -341,6 +341,7 @@ files:
|
|
341
341
|
- factsets/Windows_Server-2012r2-64.json
|
342
342
|
- factsets/solaris-10_u9-sparc-64.json
|
343
343
|
- factsets/solaris-11.2-sparc-64.json
|
344
|
+
- factsets/windows-10-64.json
|
344
345
|
- features/cache.feature
|
345
346
|
- features/help.feature
|
346
347
|
- features/init.feature
|
@@ -364,6 +365,7 @@ files:
|
|
364
365
|
- lib/onceover/cli/show.rb
|
365
366
|
- lib/onceover/cli/update.rb
|
366
367
|
- lib/onceover/controlrepo.rb
|
368
|
+
- lib/onceover/deploy.rb
|
367
369
|
- lib/onceover/group.rb
|
368
370
|
- lib/onceover/logger.rb
|
369
371
|
- lib/onceover/node.rb
|