vagrant-ovirt4 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.kitchen.yml +43 -0
- data/Dockerfile +11 -0
- data/Gemfile +5 -1
- data/Gemfile.lock +85 -10
- data/Jenkinsfile +70 -0
- data/README.md +19 -0
- data/Rakefile +13 -2
- data/lib/vagrant-ovirt4/action/create_vm.rb +6 -3
- data/lib/vagrant-ovirt4/action/destroy_vm.rb +14 -1
- data/lib/vagrant-ovirt4/action/start_vm.rb +10 -6
- data/lib/vagrant-ovirt4/action/wait_till_down.rb +13 -2
- data/lib/vagrant-ovirt4/action/wait_till_up.rb +2 -2
- data/lib/vagrant-ovirt4/errors.rb +4 -0
- data/lib/vagrant-ovirt4/plugin.rb +3 -3
- data/lib/vagrant-ovirt4/version.rb +1 -1
- data/locales/en.yml +3 -1
- data/templates/Vagrantfile.erb +199 -0
- data/test/Vagrantfile +19 -0
- data/test/integration/dynamic_network/network_spec.rb +6 -0
- data/test/integration/singleton-static_network/network_spec.rb +11 -0
- data/tools/prepare_redhat_for_box.sh +6 -1
- data/vagrant-ovirt4.gemspec +1 -1
- metadata +14 -12
- data/lib/vagrant-ovirt4/cap/nic_mac_addresses.rb +0 -15
- data/test.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 98f8665c91ae33cacd1b23a01fde88fd161d70ca
|
4
|
+
data.tar.gz: e75f2ccf4c185fd9f81d0051faa0e531a24028cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e627217298b55312ca32b2f37bf0eba8e1aec5690c4cb70a057000c755cf15cc3d3004fa86af1cba7f196fa6c5c79e3ed2d6b2b073ebaf6654a1fda4da89371a
|
7
|
+
data.tar.gz: 9c3713a833df38fc8eeb47aee1bdd8d122755a5daa3ec0e1529f523cddd52b209ac3a47c7b2779bc26d197b393221c837f5daf50dabc213b427adf8f7fd99666
|
data/.gitignore
CHANGED
data/.kitchen.yml
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
driver:
|
2
|
+
name: vagrant
|
3
|
+
vagrantfile_erb: templates/Vagrantfile.erb
|
4
|
+
provider: ovirt4
|
5
|
+
|
6
|
+
verifier:
|
7
|
+
name: inspec
|
8
|
+
format: doc
|
9
|
+
|
10
|
+
platforms:
|
11
|
+
- name: centos7
|
12
|
+
driver_plugin: vagrant
|
13
|
+
driver_config:
|
14
|
+
customize:
|
15
|
+
memory_size: 1024 MB
|
16
|
+
url: <%= ENV['OVIRT_URL'] %>
|
17
|
+
insecure: true
|
18
|
+
username: <%= ENV['OVIRT_USERNAME'] %>
|
19
|
+
password: <%= ENV['OVIRT_PASSWORD'] %>
|
20
|
+
cluster: Default
|
21
|
+
debug: true
|
22
|
+
box: ovirt4
|
23
|
+
box_url: https://github.com/myoung34/vagrant-ovirt4/blob/master/example_box/dummy.box?raw=true
|
24
|
+
|
25
|
+
suites:
|
26
|
+
- name: singleton-static_network
|
27
|
+
driver_config:
|
28
|
+
vm_hostname: static
|
29
|
+
customize:
|
30
|
+
template: vagrant-centos7
|
31
|
+
network:
|
32
|
+
- ["private_network", {ovirt__ip: <%= "192.168.2.254" %>, ovirt__network_name: 'ovirtmgmt', ovirt__gateway: 192.168.2.1, ovirt__netmask: 255.255.255.0, ovirt__dns_servers: 192.168.2.1}]
|
33
|
+
- name: dynamic_network
|
34
|
+
driver_config:
|
35
|
+
vm_hostname: dynamic
|
36
|
+
network:
|
37
|
+
- ["private_network", {ovirt__network_name: 'ovirtmgmt'}]
|
38
|
+
customize:
|
39
|
+
template: vagrant-centos7
|
40
|
+
cloud_init: |
|
41
|
+
runcmd:
|
42
|
+
- ifdown eth0
|
43
|
+
- service network restart
|
data/Dockerfile
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
FROM ruby:2.2.6
|
2
|
+
ARG jenkins_uid=997
|
3
|
+
ARG jenkins_gid=994
|
4
|
+
ENV JENKINS_UID=$jenkins_uid
|
5
|
+
ENV JENKINS_GID=$jenkins_gid
|
6
|
+
RUN apt-get update && apt-get install -y sudo
|
7
|
+
RUN groupadd -g $JENKINS_GID jenkins
|
8
|
+
RUN useradd jenkins -u $JENKINS_UID -g $JENKINS_GID --shell /bin/bash --create-home
|
9
|
+
RUN echo '%jenkins ALL=NOPASSWD: ALL' >> /etc/sudoers
|
10
|
+
RUN chown -R :jenkins /usr/local/bundle /usr/local/bin
|
11
|
+
USER jenkins
|
data/Gemfile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
source 'http://rubygems.org'
|
2
2
|
|
3
3
|
group :development do
|
4
|
-
gem 'vagrant', :git => 'git://github.com/
|
4
|
+
gem 'vagrant', :git => 'git://github.com/myoung34/vagrant.git'
|
5
5
|
gem 'pry'
|
6
6
|
gem 'byebug'
|
7
7
|
gem 'pry-byebug'
|
@@ -11,6 +11,10 @@ group :testing do
|
|
11
11
|
gem 'rspec-its'
|
12
12
|
gem 'rspec'
|
13
13
|
gem 'rake'
|
14
|
+
gem 'kitchen-vagrant'
|
15
|
+
gem 'kitchen-inspec'
|
16
|
+
gem 'test-kitchen'
|
17
|
+
gem 'net-scp', "~>1.2"
|
14
18
|
end
|
15
19
|
|
16
20
|
group :plugins do
|
data/Gemfile.lock
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
GIT
|
2
|
-
remote: git://github.com/
|
3
|
-
revision:
|
2
|
+
remote: git://github.com/myoung34/vagrant.git
|
3
|
+
revision: 4572267c33f4ba569f68ad4bff026e9a7ef63b56
|
4
4
|
specs:
|
5
|
-
vagrant (1.9.
|
5
|
+
vagrant (1.9.3.dev)
|
6
6
|
childprocess (~> 0.5.0)
|
7
7
|
erubis (~> 2.7.0)
|
8
8
|
hashicorp-checkpoint (~> 0.1.1)
|
9
9
|
i18n (>= 0.6.0, <= 0.8.0)
|
10
10
|
listen (~> 3.1.5)
|
11
11
|
log4r (~> 1.1.9, < 1.1.11)
|
12
|
-
net-scp (~> 1.
|
12
|
+
net-scp (~> 1.2.0)
|
13
13
|
net-sftp (~> 2.1)
|
14
14
|
net-ssh (~> 3.0.1)
|
15
15
|
nokogiri (= 1.6.7.1)
|
@@ -24,22 +24,30 @@ GIT
|
|
24
24
|
PATH
|
25
25
|
remote: .
|
26
26
|
specs:
|
27
|
-
vagrant-ovirt4 (1.
|
27
|
+
vagrant-ovirt4 (1.2.0)
|
28
28
|
filesize (~> 0)
|
29
|
-
ovirt-engine-sdk (~> 4.0
|
29
|
+
ovirt-engine-sdk (~> 4.0.1)
|
30
30
|
|
31
31
|
GEM
|
32
32
|
remote: http://rubygems.org/
|
33
33
|
specs:
|
34
|
+
artifactory (2.7.0)
|
35
|
+
blankslate (2.1.2.4)
|
34
36
|
builder (3.2.3)
|
35
37
|
byebug (9.0.6)
|
36
38
|
childprocess (0.5.9)
|
37
39
|
ffi (~> 1.0, >= 1.0.11)
|
38
40
|
coderay (1.1.1)
|
39
41
|
diff-lcs (1.3)
|
40
|
-
|
42
|
+
docker-api (1.33.2)
|
43
|
+
excon (>= 0.38.0)
|
44
|
+
json
|
45
|
+
domain_name (0.5.20170223)
|
41
46
|
unf (>= 0.0.5, < 1.0.0)
|
42
47
|
erubis (2.7.0)
|
48
|
+
excon (0.55.0)
|
49
|
+
faraday (0.11.0)
|
50
|
+
multipart-post (>= 1.2, < 3)
|
43
51
|
ffi (1.9.17)
|
44
52
|
filesize (0.1.1)
|
45
53
|
gssapi (1.2.0)
|
@@ -47,11 +55,35 @@ GEM
|
|
47
55
|
gyoku (1.3.1)
|
48
56
|
builder (>= 2.1.2)
|
49
57
|
hashicorp-checkpoint (0.1.4)
|
58
|
+
hashie (3.5.5)
|
50
59
|
http-cookie (1.0.3)
|
51
60
|
domain_name (~> 0.5)
|
52
61
|
httpclient (2.8.3)
|
53
62
|
i18n (0.8.0)
|
63
|
+
inspec (1.15.0)
|
64
|
+
faraday (>= 0.9.0)
|
65
|
+
hashie (~> 3.4)
|
66
|
+
json (>= 1.8, < 3.0)
|
67
|
+
method_source (~> 0.8)
|
68
|
+
mixlib-log
|
69
|
+
parallel (~> 1.9)
|
70
|
+
pry (~> 0)
|
71
|
+
rainbow (~> 2)
|
72
|
+
rspec (~> 3)
|
73
|
+
rspec-its (~> 1.2)
|
74
|
+
rspec_junit_formatter (~> 0.2.3)
|
75
|
+
rubyzip (~> 1.1)
|
76
|
+
sslshake (~> 1)
|
77
|
+
thor (~> 0.19)
|
78
|
+
toml (~> 0.1)
|
79
|
+
train (>= 0.22.0, < 1.0)
|
54
80
|
json (2.0.3)
|
81
|
+
kitchen-inspec (0.17.0)
|
82
|
+
hashie (~> 3.4)
|
83
|
+
inspec (>= 0.34.0, < 2.0.0)
|
84
|
+
test-kitchen (~> 1.6)
|
85
|
+
kitchen-vagrant (1.0.2)
|
86
|
+
test-kitchen (~> 1.4)
|
55
87
|
listen (3.1.5)
|
56
88
|
rb-fsevent (~> 0.9, >= 0.9.4)
|
57
89
|
rb-inotify (~> 0.9, >= 0.9.7)
|
@@ -66,18 +98,32 @@ GEM
|
|
66
98
|
mime-types-data (~> 3.2015)
|
67
99
|
mime-types-data (3.2016.0521)
|
68
100
|
mini_portile2 (2.0.0)
|
101
|
+
mixlib-install (2.1.12)
|
102
|
+
artifactory
|
103
|
+
mixlib-shellout
|
104
|
+
mixlib-versioning
|
105
|
+
thor
|
106
|
+
mixlib-log (1.7.1)
|
107
|
+
mixlib-shellout (2.2.7)
|
108
|
+
mixlib-versioning (1.1.0)
|
69
109
|
multi_json (1.12.1)
|
70
|
-
|
110
|
+
multipart-post (2.0.0)
|
111
|
+
net-scp (1.2.1)
|
71
112
|
net-ssh (>= 2.6.5)
|
72
113
|
net-sftp (2.1.2)
|
73
114
|
net-ssh (>= 2.6.5)
|
74
115
|
net-ssh (3.0.2)
|
116
|
+
net-ssh-gateway (1.3.0)
|
117
|
+
net-ssh (>= 2.6.5)
|
75
118
|
netrc (0.11.0)
|
76
119
|
nokogiri (1.6.7.1)
|
77
120
|
mini_portile2 (~> 2.0.0.rc2)
|
78
121
|
nori (2.6.0)
|
79
|
-
ovirt-engine-sdk (4.
|
122
|
+
ovirt-engine-sdk (4.0.12)
|
80
123
|
json
|
124
|
+
parallel (1.10.0)
|
125
|
+
parslet (1.5.0)
|
126
|
+
blankslate (~> 2.0)
|
81
127
|
pry (0.10.4)
|
82
128
|
coderay (~> 1.1.0)
|
83
129
|
method_source (~> 0.8.1)
|
@@ -85,13 +131,14 @@ GEM
|
|
85
131
|
pry-byebug (3.4.0)
|
86
132
|
byebug (~> 9.0)
|
87
133
|
pry (~> 0.10)
|
134
|
+
rainbow (2.2.1)
|
88
135
|
rake (0.9.6)
|
89
136
|
rb-fsevent (0.9.8)
|
90
137
|
rb-inotify (0.9.8)
|
91
138
|
ffi (>= 0.5.0)
|
92
139
|
rb-kqueue (0.2.4)
|
93
140
|
ffi (>= 0.5.0)
|
94
|
-
rest-client (2.0.
|
141
|
+
rest-client (2.0.1)
|
95
142
|
http-cookie (>= 1.0.2, < 2.0)
|
96
143
|
mime-types (>= 1.16, < 4.0)
|
97
144
|
netrc (~> 0.8)
|
@@ -111,10 +158,34 @@ GEM
|
|
111
158
|
diff-lcs (>= 1.2.0, < 2.0)
|
112
159
|
rspec-support (~> 3.5.0)
|
113
160
|
rspec-support (3.5.0)
|
161
|
+
rspec_junit_formatter (0.2.3)
|
162
|
+
builder (< 4)
|
163
|
+
rspec-core (>= 2, < 4, != 2.12.0)
|
114
164
|
ruby_dep (1.3.1)
|
115
165
|
rubyntlm (0.6.1)
|
116
166
|
rubyzip (1.2.1)
|
167
|
+
safe_yaml (1.0.4)
|
117
168
|
slop (3.6.0)
|
169
|
+
sslshake (1.0.13)
|
170
|
+
test-kitchen (1.15.0)
|
171
|
+
mixlib-install (>= 1.2, < 3.0)
|
172
|
+
mixlib-shellout (>= 1.2, < 3.0)
|
173
|
+
net-scp (~> 1.1)
|
174
|
+
net-ssh (>= 2.9, < 5.0)
|
175
|
+
net-ssh-gateway (~> 1.2)
|
176
|
+
safe_yaml (~> 1.0)
|
177
|
+
thor (~> 0.18)
|
178
|
+
thor (0.19.4)
|
179
|
+
toml (0.1.2)
|
180
|
+
parslet (~> 1.5.0)
|
181
|
+
train (0.22.1)
|
182
|
+
docker-api (~> 1.26)
|
183
|
+
json (>= 1.8, < 3.0)
|
184
|
+
mixlib-shellout (~> 2.0)
|
185
|
+
net-scp (~> 1.2)
|
186
|
+
net-ssh (>= 2.9, < 5.0)
|
187
|
+
winrm (~> 2.0)
|
188
|
+
winrm-fs (~> 1.0)
|
118
189
|
unf (0.1.4)
|
119
190
|
unf_ext
|
120
191
|
unf_ext (0.0.7.2)
|
@@ -142,11 +213,15 @@ PLATFORMS
|
|
142
213
|
|
143
214
|
DEPENDENCIES
|
144
215
|
byebug
|
216
|
+
kitchen-inspec
|
217
|
+
kitchen-vagrant
|
218
|
+
net-scp (~> 1.2)
|
145
219
|
pry
|
146
220
|
pry-byebug
|
147
221
|
rake
|
148
222
|
rspec
|
149
223
|
rspec-its
|
224
|
+
test-kitchen
|
150
225
|
vagrant!
|
151
226
|
vagrant-ovirt4!
|
152
227
|
|
data/Jenkinsfile
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
#!/usr/bin/env groovy
|
2
|
+
node {
|
3
|
+
stage('Checkout') {
|
4
|
+
checkout scm
|
5
|
+
}
|
6
|
+
|
7
|
+
// Run as many tests as possible in parallel.
|
8
|
+
String[] vagrantVersions = ["1.9.1", "1.9.2"]
|
9
|
+
stage('Test') {
|
10
|
+
|
11
|
+
def buildJobs = [:]
|
12
|
+
|
13
|
+
buildJobs["rspec"] = {
|
14
|
+
docker.build("jenkins/ruby:2.2.6").inside('-v /opt/gemcache:/opt/gemcache') {
|
15
|
+
sh """#!/bin/bash -ex
|
16
|
+
bundle install --path /opt/gemcache
|
17
|
+
bundle exec rspec
|
18
|
+
"""
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
for (int i = 0; i < vagrantVersions.length; i++) {
|
23
|
+
def index = i //if we tried to use i below, it would equal 4 in each job execution.
|
24
|
+
def vagrantVersion = vagrantVersions[index]
|
25
|
+
|
26
|
+
buildJobs["vagrant-${vagrantVersion}"] = {
|
27
|
+
|
28
|
+
docker.image("myoung34/vagrant:${vagrantVersion}").inside('-v /opt/gemcache:/opt/gemcache') {
|
29
|
+
sh """#!/bin/bash -ex
|
30
|
+
temp_dir="/tmp/\$(cat /proc/sys/kernel/random/uuid)"
|
31
|
+
cp -r \$(pwd) \$temp_dir
|
32
|
+
cd \$temp_dir
|
33
|
+
gem build *.gemspec
|
34
|
+
/usr/bin/vagrant plugin install *.gem
|
35
|
+
bundle install --path /opt/gemcache --without development plugins
|
36
|
+
export VAGRANT_VERSION=\$(echo ${vagrantVersion} | sed 's/\\.//g')
|
37
|
+
bundle exec kitchen test ^[^singleton-]
|
38
|
+
"""
|
39
|
+
}
|
40
|
+
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
parallel( buildJobs )
|
45
|
+
}
|
46
|
+
|
47
|
+
for (int i = 0; i < vagrantVersions.length; i++) {
|
48
|
+
def index = i //if we tried to use i below, it would equal 4 in each job execution.
|
49
|
+
def vagrantVersion = vagrantVersions[index]
|
50
|
+
|
51
|
+
|
52
|
+
stage("singleton vagrant-${vagrantVersion}") {
|
53
|
+
docker.image("myoung34/vagrant:${vagrantVersion}").inside('-v /opt/gemcache:/opt/gemcache') {
|
54
|
+
sh """#!/bin/bash -ex
|
55
|
+
gem build *.gemspec
|
56
|
+
/usr/bin/vagrant plugin install *.gem
|
57
|
+
bundle install --path /opt/gemcache --without development plugins
|
58
|
+
bundle exec kitchen destroy all
|
59
|
+
rm -rf .kitchen
|
60
|
+
export VAGRANT_VERSION=\$(echo ${vagrantVersion} | sed 's/\\.//g')
|
61
|
+
bundle exec kitchen test ^singleton-
|
62
|
+
"""
|
63
|
+
}
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
stage("Cleanup") {
|
68
|
+
deleteDir()
|
69
|
+
}
|
70
|
+
}
|
data/README.md
CHANGED
@@ -121,6 +121,25 @@ end
|
|
121
121
|
1. `placement_host` => The host to start the VM on. Optional.
|
122
122
|
|
123
123
|
|
124
|
+
## Testing
|
125
|
+
|
126
|
+
Currently pull-requests are tested via [test-kitchen using kitchen-vagrant](https://github.com/test-kitchen/kitchen-vagrant).
|
127
|
+
See [Jenkinsfile](Jenkinsfile) for more information.
|
128
|
+
If you'd like to run them yourself, however, they make not work in all setups. For example they assume `192.168.2.0/24`, host pinning will probably not have a host that's in all set ups, and the template names might not match.
|
129
|
+
|
130
|
+
To run Unit tests: `bundle install; bundle exec rspec`
|
131
|
+
|
132
|
+
To run acceptance tests:
|
133
|
+
|
134
|
+
```bash
|
135
|
+
export OVIRT_URL='https://yoururl/ovirt-engine/api''
|
136
|
+
export OVIRT_USERNAME='yourname@internal'
|
137
|
+
export OVIRT_PASSWORD='yourpassword!'
|
138
|
+
gem build *.gemspec
|
139
|
+
vagrant plugin install *.gem
|
140
|
+
bundle exec kitchen test all
|
141
|
+
```
|
142
|
+
|
124
143
|
## Contributing
|
125
144
|
|
126
145
|
1. Fork it
|
data/Rakefile
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'bundler/setup'
|
3
3
|
require 'rspec/core/rake_task'
|
4
|
+
require 'kitchen/rake_tasks'
|
4
5
|
|
5
6
|
# Immediately sync all stdout so that tools like buildbot can
|
6
7
|
# immediately load in the output.
|
@@ -18,5 +19,15 @@ Bundler::GemHelper.install_tasks
|
|
18
19
|
RSpec::Core::RakeTask.new(:spec) do |t|
|
19
20
|
t.rspec_opts = "--order defined"
|
20
21
|
end
|
21
|
-
|
22
|
-
task
|
22
|
+
|
23
|
+
# Default task is to run all tests
|
24
|
+
namespace :test do
|
25
|
+
task :all do
|
26
|
+
RSpec::Core::RakeTask.new(:spec)
|
27
|
+
Rake::Task["spec"].execute
|
28
|
+
Kitchen::RakeTasks.new
|
29
|
+
Rake::Task['kitchen:all'].invoke
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
task :default => 'test:all'
|
@@ -66,10 +66,12 @@ module VagrantPlugins
|
|
66
66
|
begin
|
67
67
|
server = env[:vms_service].add(attr)
|
68
68
|
rescue OvirtSDK4::Error => e
|
69
|
+
fault_message = /Fault detail is \"\[?(.+?)\]?\".*/.match(e.message)[1] rescue e.message
|
70
|
+
retry if e.message =~ /Related operation is currently in progress/
|
71
|
+
|
69
72
|
if config.debug
|
70
73
|
raise e
|
71
74
|
else
|
72
|
-
fault_message = /Fault detail is \"\[?(.+?)\]?\".*/.match(e.message)[1] rescue e.message
|
73
75
|
raise Errors::CreateVMError,
|
74
76
|
:error_message => fault_message
|
75
77
|
end
|
@@ -81,17 +83,18 @@ module VagrantPlugins
|
|
81
83
|
# Wait till all volumes are ready.
|
82
84
|
env[:ui].info(I18n.t("vagrant_ovirt4.wait_for_ready_vm"))
|
83
85
|
for i in 0..300
|
84
|
-
|
86
|
+
disk_ready = true
|
85
87
|
vm_service = env[:vms_service].vm_service(env[:machine].id)
|
86
88
|
disk_attachments_service = vm_service.disk_attachments_service
|
87
89
|
disk_attachments = disk_attachments_service.list
|
88
90
|
disk_attachments.each do |disk_attachment|
|
89
91
|
disk = env[:connection].follow_link(disk_attachment.disk)
|
90
92
|
if disk.status != 'ok'
|
91
|
-
|
93
|
+
disk_ready = false
|
92
94
|
break
|
93
95
|
end
|
94
96
|
end
|
97
|
+
ready = (disk_ready and env[:vms_service].vm_service(server.id).get.status.to_sym == :down)
|
95
98
|
break if ready
|
96
99
|
sleep 2
|
97
100
|
end
|
@@ -14,7 +14,20 @@ module VagrantPlugins
|
|
14
14
|
env[:ui].info(I18n.t("vagrant_ovirt4.destroy_vm"))
|
15
15
|
|
16
16
|
vm_service = env[:vms_service].vm_service(env[:machine].id)
|
17
|
-
|
17
|
+
begin
|
18
|
+
vm_service.remove
|
19
|
+
rescue OvirtSDK4::Error => e
|
20
|
+
fault_message = /Fault detail is \"\[?(.+?)\]?\".*/.match(e.message)[1] rescue e.message
|
21
|
+
retry if e.message =~ /Please try again/
|
22
|
+
|
23
|
+
if config.debug
|
24
|
+
raise e
|
25
|
+
else
|
26
|
+
raise Errors::RemoveVMError,
|
27
|
+
:error_message => fault_message
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
18
31
|
env[:machine].id = nil
|
19
32
|
|
20
33
|
@app.call(env)
|
@@ -85,12 +85,16 @@ module VagrantPlugins
|
|
85
85
|
vm: vm_configuration
|
86
86
|
)
|
87
87
|
rescue OvirtSDK4::Error => e
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
88
|
+
fault_message = /Fault detail is \"\[?(.+?)\]?\".*/.match(e.message)[1] rescue e.message
|
89
|
+
retry if e.message =~ /Please try again/
|
90
|
+
|
91
|
+
if e.message !~ /VM is running/
|
92
|
+
if config.debug
|
93
|
+
raise e
|
94
|
+
else
|
95
|
+
raise Errors::StartVMError,
|
96
|
+
:error_message => fault_message
|
97
|
+
end
|
94
98
|
end
|
95
99
|
|
96
100
|
end
|
@@ -21,10 +21,21 @@ module VagrantPlugins
|
|
21
21
|
env[:ui].info(I18n.t("vagrant_ovirt4.wait_till_down"))
|
22
22
|
for i in 1..300
|
23
23
|
ready = true
|
24
|
-
|
25
|
-
|
24
|
+
begin
|
25
|
+
if vm_service.get == nil
|
26
|
+
raise NoVMError, :error_message => '', :vm_id => env[:machine].id
|
27
|
+
end
|
28
|
+
rescue OvirtSDK4::Error => e
|
29
|
+
fault_message = /Fault detail is \"\[?(.+?)\]?\".*/.match(e.message)[1] rescue e.message
|
30
|
+
if config.debug
|
31
|
+
raise e
|
32
|
+
else
|
33
|
+
raise Errors::NoVMError, :error_message => fault_message, :vm_id => env[:machine].id
|
34
|
+
end
|
26
35
|
end
|
27
36
|
|
37
|
+
|
38
|
+
|
28
39
|
if vm_service.get.status.to_sym != :down
|
29
40
|
ready = false
|
30
41
|
end
|
@@ -33,7 +33,7 @@ module VagrantPlugins
|
|
33
33
|
# Get VM.
|
34
34
|
server = env[:vms_service].vm_service(env[:machine].id)
|
35
35
|
if server == nil
|
36
|
-
raise NoVMError, :vm_name => ''
|
36
|
+
raise Errors::NoVMError, :vm_name => ''
|
37
37
|
end
|
38
38
|
|
39
39
|
nics_service = server.nics_service
|
@@ -49,7 +49,7 @@ module VagrantPlugins
|
|
49
49
|
end
|
50
50
|
terminate(env) if env[:interrupted]
|
51
51
|
if env[:ip_address].nil?
|
52
|
-
raise NoIPError
|
52
|
+
raise Errors::NoIPError
|
53
53
|
else
|
54
54
|
@logger.info("Got IP address #{env[:ip_address]}")
|
55
55
|
@logger.info("Time for getting IP: #{env[:metrics]["instance_ip_time"]}")
|
@@ -8,9 +8,9 @@ end
|
|
8
8
|
|
9
9
|
# This is a sanity check to make sure no one is attempting to install
|
10
10
|
# this into an early Vagrant version.
|
11
|
-
# Note: snapshots only available in 1.
|
12
|
-
if Vagrant::VERSION < '1.
|
13
|
-
raise "The Vagrant oVirt v4 plugin is only compatible with Vagrant 1.
|
11
|
+
# Note: snapshots only available in 1.9.1+
|
12
|
+
if Vagrant::VERSION < '1.9.1'
|
13
|
+
raise "The Vagrant oVirt v4 plugin is only compatible with Vagrant 1.9.1+"
|
14
14
|
end
|
15
15
|
|
16
16
|
module VagrantPlugins
|
data/locales/en.yml
CHANGED
@@ -54,8 +54,10 @@ en:
|
|
54
54
|
short_down: |-
|
55
55
|
down
|
56
56
|
errors:
|
57
|
+
remove_vm_error: |-
|
58
|
+
Error removing VM '%{vm_name}'. oVirt error message was '%{error_message}'
|
57
59
|
no_vm_error: |-
|
58
|
-
No VM %{
|
60
|
+
No VM found with id '%{vm_id}'. oVirt error message was '%{error_message}'.
|
59
61
|
create_vm_error: |-
|
60
62
|
Creation failed. oVirt error message was '%{error_message}'
|
61
63
|
start_vm_error: |-
|
@@ -0,0 +1,199 @@
|
|
1
|
+
<% config[:vagrantfiles].each do |vagrantfile| %>
|
2
|
+
require "<%= vagrantfile %>"
|
3
|
+
require 'securerandom'
|
4
|
+
<% end %>
|
5
|
+
|
6
|
+
Vagrant.configure("2") do |c|
|
7
|
+
c.berkshelf.enabled = false if Vagrant.has_plugin?("vagrant-berkshelf")
|
8
|
+
<% if config[:cachier] %>
|
9
|
+
if Vagrant.has_plugin?("vagrant-cachier")
|
10
|
+
c.cache.scope = <%= [':box', ':machine'].include?(config[:cachier]) ? config[:cachier] : ':box' %>
|
11
|
+
end
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
c.vm.box = "<%= config[:box] %>"
|
15
|
+
|
16
|
+
<% if config[:box_url] %>
|
17
|
+
c.vm.box_url = "<%= config[:box_url] %>"
|
18
|
+
<% end %>
|
19
|
+
|
20
|
+
<% if config[:box_version] %>
|
21
|
+
c.vm.box_version = "<%= config[:box_version] %>"
|
22
|
+
<% end %>
|
23
|
+
|
24
|
+
<% if !config[:box_check_update].nil? %>
|
25
|
+
c.vm.box_check_update = <%= config[:box_check_update] %>
|
26
|
+
<% end %>
|
27
|
+
|
28
|
+
<% if !config[:box_download_ca_cert].nil? %>
|
29
|
+
c.vm.box_download_ca_cert = "<%= config[:box_download_ca_cert] %>"
|
30
|
+
<% end %>
|
31
|
+
|
32
|
+
<% if !config[:box_download_insecure].nil? %>
|
33
|
+
c.vm.box_download_insecure = "<%= config[:box_download_insecure] %>"
|
34
|
+
<% end %>
|
35
|
+
|
36
|
+
<% if config[:vm_hostname] %>
|
37
|
+
c.vm.hostname = "kitchen-<%= config[:vm_hostname] %>-<%= ENV['VAGRANT_VERSION'] %>-<%= SecureRandom.uuid %>"
|
38
|
+
<% end %>
|
39
|
+
|
40
|
+
<% if config[:communicator] %>
|
41
|
+
c.vm.communicator = "<%= config[:communicator] %>"
|
42
|
+
<% end %>
|
43
|
+
|
44
|
+
<% if config[:guest] %>
|
45
|
+
c.vm.guest = "<%= config[:guest] %>"
|
46
|
+
<% end %>
|
47
|
+
|
48
|
+
<% if config[:communicator] %>
|
49
|
+
<% if config[:username] %>
|
50
|
+
c.<%= config[:communicator] %>.username = "<%= config[:username] %>"
|
51
|
+
<% end %>
|
52
|
+
<% if config[:password] %>
|
53
|
+
c.<%= config[:communicator] %>.password = "<%= config[:password] %>"
|
54
|
+
<% end %>
|
55
|
+
<% else %>
|
56
|
+
<% if config[:username] %>
|
57
|
+
c.ssh.username = "<%= config[:username] %>"
|
58
|
+
<% end %>
|
59
|
+
<% if config[:password] %>
|
60
|
+
c.ssh.password = "<%= config[:password] %>"
|
61
|
+
<% end %>
|
62
|
+
<% end %>
|
63
|
+
|
64
|
+
<% if config[:ssh_key] %>
|
65
|
+
c.ssh.private_key_path = "<%= config[:ssh_key] %>"
|
66
|
+
<% end %>
|
67
|
+
<% config[:ssh].each do |key, value| %>
|
68
|
+
c.ssh.<%= key %> = <%= [true, false].include?(value) ? value : value.inspect %>
|
69
|
+
<% end %>
|
70
|
+
<% if config[:winrm] %>
|
71
|
+
<% config[:winrm].each do |key, value| %>
|
72
|
+
c.winrm.<%= key %> = <%= value %>
|
73
|
+
<% end %>
|
74
|
+
<% end %>
|
75
|
+
|
76
|
+
<% if config[:boot_timeout] %>
|
77
|
+
c.vm.boot_timeout = <%= config[:boot_timeout] %>
|
78
|
+
<% end %>
|
79
|
+
|
80
|
+
<% Array(config[:network]).each do |opts| %>
|
81
|
+
c.vm.network(:<%= opts[0] %>, <%= opts[1..-1].join(", ") %>)
|
82
|
+
<% end %>
|
83
|
+
|
84
|
+
c.vm.synced_folder ".", "/vagrant", disabled: true
|
85
|
+
<% config[:synced_folders].each do |source, destination, options| %>
|
86
|
+
c.vm.synced_folder <%= source.inspect %>, <%= destination.inspect %>, <%= options %>
|
87
|
+
<% end %>
|
88
|
+
|
89
|
+
c.vm.provider :<%= config[:provider] %> do |p|
|
90
|
+
<% case config[:provider]
|
91
|
+
when "virtualbox", /^vmware_/
|
92
|
+
if config[:gui] == true || config[:gui] == false %>
|
93
|
+
p.gui = <%= config[:gui] %>
|
94
|
+
<% end
|
95
|
+
end
|
96
|
+
|
97
|
+
case config[:provider]
|
98
|
+
when "virtualbox", /^vmware_/, "parallels"
|
99
|
+
if config[:linked_clone] == true || config[:linked_clone] == false %>
|
100
|
+
p.linked_clone = <%= config[:linked_clone] %>
|
101
|
+
<% end
|
102
|
+
end %>
|
103
|
+
|
104
|
+
<% config[:customize].each do |key, value| %>
|
105
|
+
<% case config[:provider]
|
106
|
+
when "libvirt" %>
|
107
|
+
<% if key == :storage %>
|
108
|
+
<% if value.is_a? String %>
|
109
|
+
p.storage <%= value %>
|
110
|
+
<% elsif value.is_a? Array %>
|
111
|
+
<% value.each do |v| %>
|
112
|
+
p.storage <%= v %>
|
113
|
+
<% end %>
|
114
|
+
<% end %>
|
115
|
+
<% else %>
|
116
|
+
<% if value.is_a? String %>
|
117
|
+
p.<%= key %> = "<%= value%>"
|
118
|
+
<% else %>
|
119
|
+
p.<%= key %> = <%= value%>
|
120
|
+
<% end %>
|
121
|
+
<% end %>
|
122
|
+
<% when "lxc" %>
|
123
|
+
<% if key == :container_name %>
|
124
|
+
p.container_name = <%= value == ":machine" ? value : "\"#{value}\"" %>
|
125
|
+
<% elsif key == :backingstore %>
|
126
|
+
p.backingstore = "<%= value %>"
|
127
|
+
<% elsif key == :backingstore_options %>
|
128
|
+
<% config[:customize][:backingstore_options].each do |opt, opt_val| %>
|
129
|
+
p.backingstore_option "--<%= opt %>", "<%= opt_val %>"
|
130
|
+
<% end %>
|
131
|
+
<% elsif key == :include %>
|
132
|
+
<% Array(value).each do |include| %>
|
133
|
+
p.customize "<%= key %>", "<%= include %>"
|
134
|
+
<% end %>
|
135
|
+
<% else %>
|
136
|
+
p.customize "<%= key %>", "<%= value %>"
|
137
|
+
<% end %>
|
138
|
+
<% when "managed" %>
|
139
|
+
<% if key == :server %>
|
140
|
+
p.server = "<%= value %>"
|
141
|
+
<% end %>
|
142
|
+
<% when "parallels" %>
|
143
|
+
<% if key == :memory || key == :cpus %>
|
144
|
+
p.<%= key %> = <%= value %>
|
145
|
+
<% else %>
|
146
|
+
p.customize ["set", :id, "--<%= key.to_s.gsub('_', '-') %>", "<%= value %>"]
|
147
|
+
<% end %>
|
148
|
+
<% when "softlayer" %>
|
149
|
+
<% if key == :disk_capacity %>
|
150
|
+
p.<%= key %> = <%= value %>
|
151
|
+
<% else %>
|
152
|
+
p.<%= key %> = "<%= value %>"
|
153
|
+
<% end %>
|
154
|
+
<% when "virtualbox" %>
|
155
|
+
<% if key == :createhd %>
|
156
|
+
p.customize ["createhd", "--filename", "<%= value[:filename] %>", "--size", <%= value[:size] %>]
|
157
|
+
<% elsif key == :storageattach %>
|
158
|
+
<% options = [] %>
|
159
|
+
<% value.each do |storageattach_option_key, storageattach_option_value|
|
160
|
+
options << "\"--#{storageattach_option_key}\""
|
161
|
+
if storageattach_option_value.instance_of? Fixnum
|
162
|
+
options << storageattach_option_value
|
163
|
+
else
|
164
|
+
options << "\"#{storageattach_option_value}\""
|
165
|
+
end
|
166
|
+
end %>
|
167
|
+
p.customize ["storageattach", :id, <%= options.join(', ') %>]
|
168
|
+
<% elsif key == :cpuidset %>
|
169
|
+
<% ids = [] %>
|
170
|
+
<% value.each do | id |
|
171
|
+
ids << "\"#{id}\""
|
172
|
+
end %>
|
173
|
+
p.customize ["modifyvm", :id, "--cpuidset", <%= ids.join(', ') %>]
|
174
|
+
<% else %>
|
175
|
+
p.customize ["modifyvm", :id, "--<%= key %>", "<%= value %>"]
|
176
|
+
<% end %>
|
177
|
+
<% when /^vmware_/ %>
|
178
|
+
<% if key == :memory %>
|
179
|
+
<% unless config[:customize].include?(:memsize) %>
|
180
|
+
p.vmx["memsize"] = "<%= value %>"
|
181
|
+
<% end %>
|
182
|
+
<% elsif key == :cpus %>
|
183
|
+
<% unless config[:customize].include?(:numvcpus) %>
|
184
|
+
p.vmx["numvcpus"] = "<%= value %>"
|
185
|
+
<% end %>
|
186
|
+
<% else %>
|
187
|
+
p.vmx["<%= key %>"] = "<%= value %>"
|
188
|
+
<% end %>
|
189
|
+
<% when "openstack", "cloudstack", "hyperv", "ovirt3", "ovirt4", "rackspace", "aws" %>
|
190
|
+
<% if value.is_a? String %>
|
191
|
+
p.<%= key %> = "<%= value%>"
|
192
|
+
<% else %>
|
193
|
+
p.<%= key %> = <%= value%>
|
194
|
+
<% end %>
|
195
|
+
<% end %>
|
196
|
+
<% end %>
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
data/test/Vagrantfile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Vagrant.configure("2") do |config|
|
2
|
+
config.vm.box = 'ovirt4'
|
3
|
+
config.vm.hostname = "testing"
|
4
|
+
config.vm.box_url = 'https://github.com/myoung34/vagrant-ovirt4/blob/master/example_box/dummy.box?raw=true'
|
5
|
+
|
6
|
+
config.vm.network :private_network,
|
7
|
+
:ovirt__ip => '192.168.2.254', :ovirt__network_name => 'ovirtmgmt', :ovirt__gateway => '192.168.2.1',
|
8
|
+
:ovirt__netmask => '255.255.255.0', :ovirt__dns_servers => '192.168.2.1'
|
9
|
+
|
10
|
+
|
11
|
+
config.vm.provider :ovirt4 do |ovirt|
|
12
|
+
ovirt.url = 'https://ovirt/ovirt-engine/api'
|
13
|
+
ovirt.username = "#{ENV['OVIRT_TEST_USER']}"
|
14
|
+
ovirt.password = "#{ENV['OVIRT_TEST_PASS']}"
|
15
|
+
ovirt.insecure = true
|
16
|
+
ovirt.cluster = 'Default'
|
17
|
+
ovirt.template = 'vagrant-centos7'
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
describe command('uname -a') do
|
2
|
+
its(:exit_status) { should eq 0 }
|
3
|
+
its(:stderr) { should be_empty }
|
4
|
+
its(:stdout) { should match(/^Linux kitchen-static-[0-9]+-[a-f0-9\-]+/) }
|
5
|
+
end
|
6
|
+
|
7
|
+
describe command("ip route get 1 | awk '{print $NF;exit}'") do
|
8
|
+
its(:exit_status) { should eq 0 }
|
9
|
+
its(:stderr) { should be_empty }
|
10
|
+
its(:stdout) { should match(/^192.168.2.254$/) }
|
11
|
+
end
|
@@ -106,6 +106,8 @@ chkconfig iptables off
|
|
106
106
|
chkconfig firewalld off
|
107
107
|
chkconfig ip6tables off
|
108
108
|
for i in cloud-init ovirt-guest-agent; do chkconfig $i on; done
|
109
|
+
chkconfig NetworkManager off
|
110
|
+
|
109
111
|
sed -i 's/SELINUX=enforcing/SELINUX=permissive/' /etc/sysconfig/selinux
|
110
112
|
[ -f /etc/selinux/config ] && sed -i 's/SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config
|
111
113
|
|
@@ -121,8 +123,11 @@ echo $'' > /etc/sysconfig/network-scripts/ifcfg-eth0
|
|
121
123
|
CLOUD_CONFIG=/etc/cloud/cloud.cfg
|
122
124
|
grep -q ' - resolv-conf' $CLOUD_CONFIG || sed -i -e 's/ - timezone/&\n - resolv-conf/' $CLOUD_CONFIG
|
123
125
|
|
126
|
+
# Chef
|
127
|
+
[[ $ATOMIC != "true" ]] && curl -L --silent https://omnitruck.chef.io/install.sh | bash
|
128
|
+
|
129
|
+
|
124
130
|
# Do some cleanup..
|
125
131
|
rm -f /root/.bash_history
|
126
132
|
rm -f /root/authorized_keys
|
127
133
|
[[ $ATOMIC != "true" ]] && yum clean all
|
128
|
-
|
data/vagrant-ovirt4.gemspec
CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.require_paths = ["lib"]
|
17
17
|
gem.version = VagrantPlugins::OVirtProvider::VERSION
|
18
18
|
|
19
|
-
gem.add_runtime_dependency 'ovirt-engine-sdk', '~> 4.0
|
19
|
+
gem.add_runtime_dependency 'ovirt-engine-sdk', '~> 4.0.1'
|
20
20
|
gem.add_runtime_dependency 'filesize', '~> 0'
|
21
21
|
|
22
22
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vagrant-ovirt4
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marcus Young
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ovirt-engine-sdk
|
@@ -16,20 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
20
|
-
- - ">="
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: 4.0.6
|
19
|
+
version: 4.0.1
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
24
|
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
30
|
-
- - ">="
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: 4.0.6
|
26
|
+
version: 4.0.1
|
33
27
|
- !ruby/object:Gem::Dependency
|
34
28
|
name: filesize
|
35
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,9 +46,12 @@ extensions: []
|
|
52
46
|
extra_rdoc_files: []
|
53
47
|
files:
|
54
48
|
- ".gitignore"
|
49
|
+
- ".kitchen.yml"
|
55
50
|
- ".rspec"
|
51
|
+
- Dockerfile
|
56
52
|
- Gemfile
|
57
53
|
- Gemfile.lock
|
54
|
+
- Jenkinsfile
|
58
55
|
- LICENSE
|
59
56
|
- README.md
|
60
57
|
- Rakefile
|
@@ -91,7 +88,6 @@ files:
|
|
91
88
|
- lib/vagrant-ovirt4/action/wait_til_suspended.rb
|
92
89
|
- lib/vagrant-ovirt4/action/wait_till_down.rb
|
93
90
|
- lib/vagrant-ovirt4/action/wait_till_up.rb
|
94
|
-
- lib/vagrant-ovirt4/cap/nic_mac_addresses.rb
|
95
91
|
- lib/vagrant-ovirt4/cap/snapshot_list.rb
|
96
92
|
- lib/vagrant-ovirt4/cap/snapshot_save.rb
|
97
93
|
- lib/vagrant-ovirt4/config.rb
|
@@ -115,7 +111,10 @@ files:
|
|
115
111
|
- spec/vagrant-ovirt4/action/read_ssh_info_spec.rb
|
116
112
|
- spec/vagrant-ovirt4/action/read_state_spec.rb
|
117
113
|
- spec/vagrant-ovirt4/config_spec.rb
|
118
|
-
-
|
114
|
+
- templates/Vagrantfile.erb
|
115
|
+
- test/Vagrantfile
|
116
|
+
- test/integration/dynamic_network/network_spec.rb
|
117
|
+
- test/integration/singleton-static_network/network_spec.rb
|
119
118
|
- tools/prepare_redhat_for_box.sh
|
120
119
|
- vagrant-ovirt4.gemspec
|
121
120
|
homepage: https://github.com/myoung34/vagrant-ovirt4
|
@@ -156,3 +155,6 @@ test_files:
|
|
156
155
|
- spec/vagrant-ovirt4/action/read_ssh_info_spec.rb
|
157
156
|
- spec/vagrant-ovirt4/action/read_state_spec.rb
|
158
157
|
- spec/vagrant-ovirt4/config_spec.rb
|
158
|
+
- test/Vagrantfile
|
159
|
+
- test/integration/dynamic_network/network_spec.rb
|
160
|
+
- test/integration/singleton-static_network/network_spec.rb
|
@@ -1,15 +0,0 @@
|
|
1
|
-
# vim: ai ts=2 sts=2 et sw=2 ft=ruby
|
2
|
-
module VagrantPlugins
|
3
|
-
module OVirtProvider
|
4
|
-
module Cap
|
5
|
-
module NicMacAddresses
|
6
|
-
def self.nic_mac_addresses(machine)
|
7
|
-
ovirt = OVirtProvider.ovirt_connection
|
8
|
-
interfaces = ovirt.list_vm_interfaces(machine.id.to_s)
|
9
|
-
Hash[interfaces.map{ |i| [i[:name], i[:mac]] }]
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
data/test.rb
DELETED