zergrush 0.0.2 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +33 -2
- data/data/ke.schema +11 -250
- data/features/hive.feature +2 -1
- data/lib/zerg.rb +1 -2
- data/lib/zerg/erbalize.rb +35 -0
- data/lib/zerg/gem_plugin.rb +334 -0
- data/lib/zerg/hive.rb +51 -25
- data/lib/zerg/runner.rb +26 -199
- data/lib/zerg/version.rb +1 -1
- data/zerg.gemspec +3 -1
- metadata +21 -10
- data/data/driver/vagrant/bridging.template +0 -1
- data/data/driver/vagrant/hostonly.template +0 -1
- data/data/driver/vagrant/machine.template +0 -22
- data/data/driver/vagrant/main.template +0 -11
- data/data/driver/vagrant/provider.template +0 -3
- data/lib/zerg/driver_renderer.rb +0 -190
data/lib/zerg/runner.rb
CHANGED
@@ -23,212 +23,29 @@
|
|
23
23
|
|
24
24
|
require 'awesome_print'
|
25
25
|
require 'fileutils'
|
26
|
-
require 'erb'
|
27
|
-
require 'rbconfig'
|
28
26
|
|
29
27
|
module Zerg
|
30
28
|
class Runner
|
31
|
-
|
32
|
-
def check_provider(driver, provider)
|
33
|
-
if driver == "vagrant"
|
34
|
-
if provider == "aws"
|
35
|
-
aws_pid = Process.spawn("vagrant plugin list | grep vagrant-aws")
|
36
|
-
Process.wait(aws_pid)
|
37
|
-
|
38
|
-
if $?.exitstatus != 0
|
39
|
-
aws_pid = Process.spawn("vagrant plugin install vagrant-aws")
|
40
|
-
Process.wait(aws_pid)
|
41
|
-
abort("ERROR: vagrant-aws installation failed!") unless $?.exitstatus == 0
|
42
|
-
end
|
43
|
-
elsif provider == "libvirt"
|
44
|
-
abort("ERROR: libvirt is only supported on a linux host!") unless /linux|arch/i === RbConfig::CONFIG['host_os']
|
45
|
-
|
46
|
-
libvirt_pid = Process.spawn("vagrant plugin list | grep vagrant-libvirt")
|
47
|
-
Process.wait(libvirt_pid)
|
48
|
-
|
49
|
-
if $?.exitstatus != 0
|
50
|
-
libvirt_pid = Process.spawn("vagrant plugin install vagrant-libvirt")
|
51
|
-
Process.wait(libvirt_pid)
|
52
|
-
abort("ERROR: vagrant-libvirt installation failed! Refer to https://github.com/pradels/vagrant-libvirt to install missing dependencies, if any.") unless $?.exitstatus == 0
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
# cross platform way of checking if command is available in PATH
|
59
|
-
def self.which(cmd)
|
60
|
-
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
61
|
-
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
62
|
-
exts.each { |ext|
|
63
|
-
exe = File.join(path, "#{cmd}#{ext}")
|
64
|
-
return exe if File.executable? exe
|
65
|
-
}
|
66
|
-
end
|
67
|
-
return nil
|
68
|
-
end
|
69
|
-
|
70
|
-
def process(taskname, task, debug)
|
71
|
-
puts ("Will perform task #{taskname} with contents:\n #{task.ai}")
|
72
|
-
|
73
|
-
# render driver template
|
74
|
-
renderer = DriverRenderer.new(
|
75
|
-
task["vm"],
|
76
|
-
taskname,
|
77
|
-
task["instances"],
|
78
|
-
task["synced_folders"],
|
79
|
-
task["tasks"])
|
80
|
-
|
81
|
-
renderer.render
|
82
|
-
|
83
|
-
# do we need additional plugins?
|
84
|
-
task["tasks"].each { |task|
|
85
|
-
if task["type"] == "chef_client" || task["type"] == "chef_solo"
|
86
|
-
omnibus_pid = Process.spawn("vagrant plugin list | grep vagrant-omnibus")
|
87
|
-
Process.wait(omnibus_pid)
|
88
|
-
|
89
|
-
if $?.exitstatus != 0
|
90
|
-
omnibus_pid = Process.spawn("vagrant plugin install vagrant-omnibus")
|
91
|
-
Process.wait(aws_pid)
|
92
|
-
abort("ERROR: vagrant-omnibus installation failed!") unless $?.exitstatus == 0
|
93
|
-
end
|
94
|
-
break;
|
95
|
-
end
|
96
|
-
}
|
97
|
-
|
98
|
-
|
99
|
-
run(taskname, task["vm"]["driver"]["drivertype"], task["vm"]["driver"]["providertype"], task["instances"], (task["vm"]["keepalive"] == nil) ? false : task["vm"]["keepalive"], debug)
|
100
|
-
end
|
101
|
-
|
102
|
-
def cleanup(taskname, task, debug)
|
103
|
-
puts ("Will cleanup task #{taskname}...")
|
104
|
-
|
105
|
-
# TODO: generalize for multiple drivers
|
106
|
-
# render driver template
|
107
|
-
renderer = DriverRenderer.new(
|
108
|
-
task["vm"],
|
109
|
-
taskname,
|
110
|
-
task["instances"],
|
111
|
-
task["synced_folders"],
|
112
|
-
task["tasks"])
|
113
|
-
renderer.render
|
114
|
-
|
115
|
-
check_provider(task["vm"]["driver"]["drivertype"], task["vm"]["driver"]["providertype"])
|
116
|
-
|
117
|
-
# run vagrant cleanup
|
118
|
-
debug_string = (debug == true) ? " --debug" : ""
|
119
|
-
|
120
|
-
for index in 0..task["instances"] - 1
|
121
|
-
cleanup_pid = Process.spawn(
|
122
|
-
{
|
123
|
-
"VAGRANT_CWD" => File.join("#{Dir.pwd}", ".hive", "driver", task["vm"]["driver"]["drivertype"], taskname),
|
124
|
-
"VAGRANT_DEFAULT_PROVIDER" => task["vm"]["driver"]["providertype"]
|
125
|
-
},
|
126
|
-
"vagrant destroy zergling_#{index} --force#{debug_string}")
|
127
|
-
Process.wait(cleanup_pid)
|
128
|
-
abort("ERROR: vagrant failed!") unless $?.exitstatus == 0
|
129
|
-
end
|
130
|
-
|
131
|
-
cleanup_pid = Process.spawn(
|
132
|
-
{
|
133
|
-
"VAGRANT_CWD" => File.join("#{Dir.pwd}", ".hive", "driver", task["vm"]["driver"]["drivertype"], taskname)
|
134
|
-
},
|
135
|
-
"vagrant box remove zergling_#{taskname}_#{task["vm"]["driver"]["providertype"]}#{debug_string} #{task["vm"]["driver"]["providertype"]}")
|
136
|
-
Process.wait(cleanup_pid)
|
137
|
-
end
|
138
|
-
|
139
|
-
def halt(taskname, driver, provider, instances, debug)
|
140
|
-
puts("Halting all vagrant virtual machines...")
|
141
|
-
debug_string = (debug == true) ? " --debug" : ""
|
142
|
-
|
143
|
-
# halt all machines
|
144
|
-
halt_pid = nil
|
145
|
-
for index in 0..instances - 1
|
146
|
-
halt_pid = Process.spawn(
|
147
|
-
{
|
148
|
-
"VAGRANT_CWD" => File.join("#{Dir.pwd}", ".hive", "driver", driver, taskname),
|
149
|
-
"VAGRANT_DEFAULT_PROVIDER" => "#{provider}"
|
150
|
-
},
|
151
|
-
"vagrant halt zergling_#{index}#{debug_string}")
|
152
|
-
Process.wait(halt_pid)
|
153
|
-
abort("ERROR: vagrant halt failed on machine zergling_#{index}!") unless $?.exitstatus == 0
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
def run(taskname, driver, provider, instances, keepalive, debug)
|
158
|
-
check_provider(driver, provider)
|
159
|
-
|
160
|
-
debug_string = (debug == true) ? " --debug" : ""
|
161
|
-
|
162
|
-
# bring up all of the VMs first.
|
163
|
-
puts("Starting vagrant in #{File.join("#{Dir.pwd}", ".hive", "driver", driver, taskname)}")
|
164
|
-
for index in 0..instances - 1
|
165
|
-
create_pid = Process.spawn(
|
166
|
-
{
|
167
|
-
"VAGRANT_CWD" => File.join("#{Dir.pwd}", ".hive", "driver", driver, taskname)
|
168
|
-
},
|
169
|
-
"vagrant up zergling_#{index} --no-provision --provider=#{provider}#{debug_string}")
|
170
|
-
Process.wait(create_pid)
|
171
|
-
|
172
|
-
if $?.exitstatus != 0
|
173
|
-
puts "ERROR: vagrant failed while creating one of the VMs. Will clean task #{taskname}:"
|
174
|
-
self.class.clean(taskname, debug)
|
175
|
-
abort("ERROR: vagrant failed!")
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
puts("Running tasks in vagrant virtual machines...")
|
180
|
-
# and provision them all at once (sort of)
|
181
|
-
provisioners = Array.new
|
182
|
-
provision_pid = nil
|
183
|
-
for index in 0..instances - 1
|
184
|
-
provision_pid = Process.spawn(
|
185
|
-
{
|
186
|
-
"VAGRANT_CWD" => File.join("#{Dir.pwd}", ".hive", "driver", driver, taskname),
|
187
|
-
"VAGRANT_DEFAULT_PROVIDER" => "#{provider}"
|
188
|
-
},
|
189
|
-
"vagrant provision zergling_#{index}#{debug_string}")
|
190
|
-
provisioners.push({:name => "zergling_#{index}", :pid => provision_pid})
|
191
|
-
end
|
192
|
-
|
193
|
-
# wait for everything to finish...
|
194
|
-
errors = Array.new
|
195
|
-
lock = Mutex.new
|
196
|
-
provisioners.each { |provisioner|
|
197
|
-
Thread.new {
|
198
|
-
Process.wait(provisioner[:pid]);
|
199
|
-
lock.synchronize do
|
200
|
-
errors.push(provisioner[:name]) unless $?.exitstatus == 0
|
201
|
-
end
|
202
|
-
}.join
|
203
|
-
}
|
204
|
-
|
205
|
-
if keepalive == false
|
206
|
-
halt(taskname, driver, provider, instances, debug)
|
207
|
-
else
|
208
|
-
puts "Will leave instances running."
|
209
|
-
end
|
210
|
-
|
211
|
-
abort("ERROR: Finished with errors in: #{errors.to_s}") unless errors.length == 0
|
212
|
-
puts("SUCCESS!")
|
213
|
-
end
|
214
|
-
|
215
29
|
def self.rush(task, debug)
|
216
|
-
abort("ERROR: Vagrant not installed!") unless which("vagrant") != nil
|
217
|
-
|
218
30
|
# load the hive first
|
219
31
|
Zerg::Hive.instance.load
|
220
32
|
|
221
33
|
puts "Loaded hive. Looking for task #{task}..."
|
222
34
|
abort("ERROR: Task #{task} not found in current hive!") unless Zerg::Hive.instance.hive.has_key?(task)
|
223
35
|
|
224
|
-
#
|
225
|
-
|
226
|
-
|
36
|
+
# rush!
|
37
|
+
begin
|
38
|
+
pmgr = ZergGemPlugin::Manager.instance
|
39
|
+
pmgr.load
|
40
|
+
driver = pmgr.create("/driver/#{Zerg::Hive.instance.hive[task]["vm"]["driver"]["drivertype"]}")
|
41
|
+
driver.rush Zerg::Hive.instance.load_path, task, Zerg::Hive.instance.hive[task], debug
|
42
|
+
rescue ZergGemPlugin::PluginNotLoaded
|
43
|
+
abort("ERROR: driver #{Zerg::Hive.instance.hive[task]["vm"]["driver"]["drivertype"]} not found. Did you install the plugin gem?")
|
44
|
+
end
|
45
|
+
puts("SUCCESS!")
|
227
46
|
end
|
228
47
|
|
229
48
|
def self.halt(task, debug)
|
230
|
-
abort("ERROR: Vagrant not installed!") unless which("vagrant") != nil
|
231
|
-
|
232
49
|
# load the hive first
|
233
50
|
Zerg::Hive.instance.load
|
234
51
|
|
@@ -236,22 +53,32 @@ module Zerg
|
|
236
53
|
abort("ERROR: Task #{task} not found in current hive!") unless Zerg::Hive.instance.hive.has_key?(task)
|
237
54
|
|
238
55
|
# halt!
|
239
|
-
|
240
|
-
|
56
|
+
begin
|
57
|
+
pmgr = ZergGemPlugin::Manager.instance
|
58
|
+
pmgr.load
|
59
|
+
driver = pmgr.create("/driver/#{Zerg::Hive.instance.hive[task]["vm"]["driver"]["drivertype"]}")
|
60
|
+
driver.halt Zerg::Hive.instance.load_path, task, Zerg::Hive.instance.hive[task], debug
|
61
|
+
rescue ZergGemPlugin::PluginNotLoaded
|
62
|
+
abort("ERROR: driver #{Zerg::Hive.instance.hive[task]["vm"]["driver"]["drivertype"]} not found. Did you install the plugin gem?")
|
63
|
+
end
|
241
64
|
puts("SUCCESS!")
|
242
65
|
end
|
243
66
|
|
244
67
|
def self.clean(task, debug)
|
245
|
-
abort("ERROR: Vagrant not installed!") unless which("vagrant") != nil
|
246
|
-
|
247
68
|
# load the hive first
|
248
69
|
Zerg::Hive.instance.load
|
249
70
|
|
250
71
|
puts "Loaded hive. Looking for task #{task}..."
|
251
72
|
abort("ERROR: Task #{task} not found in current hive!") unless Zerg::Hive.instance.hive.has_key?(task)
|
252
73
|
|
253
|
-
|
254
|
-
|
74
|
+
begin
|
75
|
+
pmgr = ZergGemPlugin::Manager.instance
|
76
|
+
pmgr.load
|
77
|
+
driver = pmgr.create("/driver/#{Zerg::Hive.instance.hive[task]["vm"]["driver"]["drivertype"]}")
|
78
|
+
driver.clean Zerg::Hive.instance.load_path, task, Zerg::Hive.instance.hive[task], debug
|
79
|
+
rescue ZergGemPlugin::PluginNotLoaded
|
80
|
+
abort("ERROR: driver #{Zerg::Hive.instance.hive[task]["vm"]["driver"]["drivertype"]} not found. Did you install the plugin gem?")
|
81
|
+
end
|
255
82
|
puts("SUCCESS!")
|
256
83
|
end
|
257
84
|
end
|
data/lib/zerg/version.rb
CHANGED
data/zerg.gemspec
CHANGED
@@ -8,10 +8,11 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.authors = ["MTN Satellite Communications"]
|
9
9
|
s.email = ["Marat.Garafutdinov@mtnsat.com"]
|
10
10
|
s.homepage = "https://github.com/MTNSatelliteComm/zerg"
|
11
|
+
s.license = "MIT"
|
11
12
|
s.summary = "Zerg is a tool for launching an arbitrary number of virtual machines and running a task on all of them at once"
|
12
13
|
s.description = "Zerg is a tool for launching an arbitrary number of virtual machines and running a task on all of them at once"
|
13
14
|
|
14
|
-
s.required_rubygems_version = ">=
|
15
|
+
s.required_rubygems_version = ">= 2.0.0"
|
15
16
|
s.rubyforge_project = "zergrush"
|
16
17
|
|
17
18
|
s.add_development_dependency "bundler", ">= 1.0.0"
|
@@ -24,6 +25,7 @@ Gem::Specification.new do |s|
|
|
24
25
|
s.add_dependency "json-schema"
|
25
26
|
s.add_dependency "thor"
|
26
27
|
s.add_dependency "highline"
|
28
|
+
s.add_dependency "zergrush_vagrant"
|
27
29
|
|
28
30
|
s.files = `git ls-files`.split("\n")
|
29
31
|
s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zergrush
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- MTN Satellite Communications
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -136,6 +136,20 @@ dependencies:
|
|
136
136
|
- - '>='
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: zergrush_vagrant
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - '>='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - '>='
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
139
153
|
description: Zerg is a tool for launching an arbitrary number of virtual machines
|
140
154
|
and running a task on all of them at once
|
141
155
|
email:
|
@@ -151,18 +165,14 @@ files:
|
|
151
165
|
- LICENSE.txt
|
152
166
|
- Rakefile
|
153
167
|
- bin/zerg
|
154
|
-
- data/driver/vagrant/bridging.template
|
155
|
-
- data/driver/vagrant/hostonly.template
|
156
|
-
- data/driver/vagrant/machine.template
|
157
|
-
- data/driver/vagrant/main.template
|
158
|
-
- data/driver/vagrant/provider.template
|
159
168
|
- data/ke.schema
|
160
169
|
- features/hive.feature
|
161
170
|
- features/support/setup.rb
|
162
171
|
- features/task.feature
|
163
172
|
- lib/zerg.rb
|
164
173
|
- lib/zerg/cli.rb
|
165
|
-
- lib/zerg/
|
174
|
+
- lib/zerg/erbalize.rb
|
175
|
+
- lib/zerg/gem_plugin.rb
|
166
176
|
- lib/zerg/generators/hivegen.rb
|
167
177
|
- lib/zerg/generators/task/awstemplate.ke
|
168
178
|
- lib/zerg/generators/task/template.ke
|
@@ -172,7 +182,8 @@ files:
|
|
172
182
|
- spec/zerg_spec.rb
|
173
183
|
- zerg.gemspec
|
174
184
|
homepage: https://github.com/MTNSatelliteComm/zerg
|
175
|
-
licenses:
|
185
|
+
licenses:
|
186
|
+
- MIT
|
176
187
|
metadata: {}
|
177
188
|
post_install_message:
|
178
189
|
rdoc_options: []
|
@@ -187,7 +198,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
187
198
|
requirements:
|
188
199
|
- - '>='
|
189
200
|
- !ruby/object:Gem::Version
|
190
|
-
version:
|
201
|
+
version: 2.0.0
|
191
202
|
requirements: []
|
192
203
|
rubyforge_project: zergrush
|
193
204
|
rubygems_version: 2.2.2
|
@@ -1 +0,0 @@
|
|
1
|
-
<%= machine_name %>.vm.network :public_network, :bridge => "<%= bridged_eth_description %>", :mac => <%= machine_mac %>, :use_dhcp_assigned_default_route => true
|
@@ -1 +0,0 @@
|
|
1
|
-
<%= machine_name %>.vm.network :private_network, ip: "192.168.50.<%= last_octet %>"
|
@@ -1,22 +0,0 @@
|
|
1
|
-
# define the machine name
|
2
|
-
config.vm.define "<%= machine_name %>" do |<%= machine_name %>|
|
3
|
-
<%= bridge_specifics -%>
|
4
|
-
<%= hostonly_specifics %>
|
5
|
-
<%= sync_folders_array -%>
|
6
|
-
|
7
|
-
# provisioning
|
8
|
-
tasks = JSON.parse(<%= tasks_array %>)
|
9
|
-
tasks.each { |task|
|
10
|
-
if task["type"] == "chef_client" || task["type"] == "chef_solo"
|
11
|
-
<%= machine_name %>.omnibus.chef_version = :latest
|
12
|
-
end
|
13
|
-
|
14
|
-
<%= machine_name %>.vm.provision "#{task["type"]}" do |provisioner|
|
15
|
-
task.each do |key, value|
|
16
|
-
next if key == "type"
|
17
|
-
provisioner.send("#{key}=", value)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
}
|
21
|
-
end
|
22
|
-
|
@@ -1,11 +0,0 @@
|
|
1
|
-
Vagrant.configure(2) do |config|
|
2
|
-
<%= provider_section %>
|
3
|
-
|
4
|
-
config.vagrant.host = :detect
|
5
|
-
config.vm.box_url = "<%= basebox_path %>"
|
6
|
-
config.vm.box = "<%= box_name %>"
|
7
|
-
config.vm.boot_timeout = 300
|
8
|
-
config.vm.graceful_halt_timeout = 60
|
9
|
-
<%= vm_defines -%>
|
10
|
-
|
11
|
-
end
|
data/lib/zerg/driver_renderer.rb
DELETED
@@ -1,190 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
|
3
|
-
# Copyright 2014 by MTN Sattelite Communications
|
4
|
-
#
|
5
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
# of this software and associated documentation files (the "Software"), to
|
7
|
-
# deal in the Software without restriction, including without limitation the
|
8
|
-
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
9
|
-
# sell copies of the Software, and to permit persons to whom the Software is
|
10
|
-
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
13
|
-
# all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
20
|
-
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
21
|
-
# IN THE SOFTWARE.
|
22
|
-
#++
|
23
|
-
|
24
|
-
require 'awesome_print'
|
25
|
-
require 'fileutils'
|
26
|
-
require 'erb'
|
27
|
-
require 'ostruct'
|
28
|
-
require 'securerandom'
|
29
|
-
|
30
|
-
module Zerg
|
31
|
-
class DriverRenderer
|
32
|
-
class Erbalize < OpenStruct
|
33
|
-
def self.erbalize_hash(template, sources)
|
34
|
-
Erbalize.new(sources).render(template)
|
35
|
-
end
|
36
|
-
|
37
|
-
def render(template)
|
38
|
-
ERB.new(template, nil, '-').result(binding)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
# generate a virtualbox - compatible MAC address
|
43
|
-
def generateMACAddress()
|
44
|
-
firstChar = (0..255).map(&:chr).select{|x| x =~ /[0-9A-Fa-f]/}.sample(1).join
|
45
|
-
secondChar = (0..255).map(&:chr).select{|x| x =~ /[02468ACEace]/}.sample(1).join
|
46
|
-
restOfChars = (0..255).map(&:chr).select{|x| x =~ /[0-9A-Fa-f]/}.sample(10).join
|
47
|
-
return "#{firstChar}#{secondChar}#{restOfChars}"
|
48
|
-
end
|
49
|
-
|
50
|
-
def initialize(vm, name, instances, synced_folders, tasks )
|
51
|
-
@vm = vm
|
52
|
-
@name = name
|
53
|
-
@instances = instances
|
54
|
-
@tasks = tasks
|
55
|
-
@synced_folders = synced_folders
|
56
|
-
end
|
57
|
-
|
58
|
-
def render
|
59
|
-
puts ("Rendering driver templates...")
|
60
|
-
|
61
|
-
# TODO: generalize this processing better
|
62
|
-
abort("ERROR: Driver type '#{@vm["driver"]["drivertype"]} is not supported.") unless (@vm["driver"]["drivertype"] == "vagrant")
|
63
|
-
|
64
|
-
# load the template files
|
65
|
-
main_template = File.open(File.join("#{File.dirname(__FILE__)}", "..", "..", "data", "driver", "#{@vm["driver"]["drivertype"]}", "main.template"), 'r').read
|
66
|
-
|
67
|
-
# load the provider top level template
|
68
|
-
provider_parent_template = File.open(File.join("#{File.dirname(__FILE__)}", "..", "..", "data", "driver", "#{@vm["driver"]["drivertype"]}", "provider.template"), 'r').read
|
69
|
-
|
70
|
-
# load the machine details template
|
71
|
-
machine_template = File.open(File.join("#{File.dirname(__FILE__)}", "..", "..", "data", "driver", "#{@vm["driver"]["drivertype"]}", "machine.template"), 'r').read
|
72
|
-
|
73
|
-
# load the bridge details template
|
74
|
-
bridge_template = File.open(File.join("#{File.dirname(__FILE__)}", "..", "..", "data", "driver", "#{@vm["driver"]["drivertype"]}", "bridging.template"), 'r').read
|
75
|
-
|
76
|
-
# load the host only network details template
|
77
|
-
hostonly_template = File.open(File.join("#{File.dirname(__FILE__)}", "..", "..", "data", "driver", "#{@vm["driver"]["drivertype"]}", "hostonly.template"), 'r').read
|
78
|
-
|
79
|
-
# render templates....
|
80
|
-
# render provider details to string
|
81
|
-
#
|
82
|
-
# render provider details into a string
|
83
|
-
provider_details_array = @vm["driver"]["provider_options"]
|
84
|
-
provider_details = ""
|
85
|
-
for index in 0..provider_details_array.length - 1
|
86
|
-
provider_details += "\t\t" + provider_details_array[index] + "\n"
|
87
|
-
end
|
88
|
-
|
89
|
-
# render provider parent
|
90
|
-
sources = {
|
91
|
-
:provider => @vm["driver"]["providertype"],
|
92
|
-
:provider_specifics => provider_details
|
93
|
-
}
|
94
|
-
provider_parent_string = Erbalize.erbalize_hash(provider_parent_template, sources)
|
95
|
-
|
96
|
-
# render machine template
|
97
|
-
all_macs = Array.new
|
98
|
-
all_machines = ""
|
99
|
-
for index in 0..@instances - 1
|
100
|
-
|
101
|
-
# last ip octet offset for host only networking
|
102
|
-
ip_octet_offset = index
|
103
|
-
|
104
|
-
# inject randomized node_name into chef_client tasks
|
105
|
-
@tasks.each { |task|
|
106
|
-
if task["type"] == "chef_client"
|
107
|
-
task["node_name"] = "zergling_#{index}_#{SecureRandom.hex(20)}"
|
108
|
-
end
|
109
|
-
}
|
110
|
-
|
111
|
-
# tasks array rendered to ruby string. double encoding to escape quotes and allow for variable expansion
|
112
|
-
tasks_array = @tasks.to_json.to_json
|
113
|
-
|
114
|
-
# do we need the bridging template as well?
|
115
|
-
bridge_section = nil
|
116
|
-
if @vm.has_key?("bridge_description")
|
117
|
-
# mac address to use?
|
118
|
-
new_mac = ""
|
119
|
-
begin
|
120
|
-
new_mac = generateMACAddress()
|
121
|
-
end while all_macs.include? new_mac
|
122
|
-
|
123
|
-
sources = {
|
124
|
-
:machine_mac => new_mac,
|
125
|
-
:bridged_eth_description => @vm["bridge_description"]
|
126
|
-
}
|
127
|
-
bridge_section = Erbalize.erbalize_hash(bridge_template, sources)
|
128
|
-
end
|
129
|
-
|
130
|
-
# do we need the host only template as well?
|
131
|
-
hostonly_section = nil
|
132
|
-
if @vm["private_network"] == true
|
133
|
-
sources = {
|
134
|
-
:machine_name => "zergling_#{index}",
|
135
|
-
:last_octet => ip_octet_offset + 4, # TODO: this is probably specific to virtualbox networking
|
136
|
-
}
|
137
|
-
hostonly_section = Erbalize.erbalize_hash(hostonly_template, sources)
|
138
|
-
end
|
139
|
-
|
140
|
-
# blah
|
141
|
-
folder_definitions = nil
|
142
|
-
if @synced_folders != nil
|
143
|
-
folder_definitions = ""
|
144
|
-
@synced_folders.each { |folder|
|
145
|
-
other_options = ""
|
146
|
-
if folder.has_key?("options")
|
147
|
-
folder["options"].each { |option|
|
148
|
-
option.each do |key, value|
|
149
|
-
if value.is_a?(String)
|
150
|
-
other_options += ", :#{key} => \"#{value}\""
|
151
|
-
else
|
152
|
-
other_options += ", :#{key} => #{value}"
|
153
|
-
end
|
154
|
-
end
|
155
|
-
}
|
156
|
-
end
|
157
|
-
|
158
|
-
folder_definition = "zergling_#{index}.vm.synced_folder \"#{folder['host_path']}\", \"#{folder['guest_path']}\""
|
159
|
-
folder_definition = "#{folder_definition}#{other_options}" unless other_options.empty?()
|
160
|
-
folder_definitions += "\t\t#{folder_definition}\n"
|
161
|
-
}
|
162
|
-
end
|
163
|
-
|
164
|
-
sources = {
|
165
|
-
:machine_name => "zergling_#{index}",
|
166
|
-
:bridge_specifics => bridge_section,
|
167
|
-
:hostonly_specifics => hostonly_section,
|
168
|
-
:tasks_array => tasks_array,
|
169
|
-
:sync_folders_array => folder_definitions
|
170
|
-
}.delete_if { |k, v| v.nil? }
|
171
|
-
|
172
|
-
machine_section = Erbalize.erbalize_hash(machine_template, sources)
|
173
|
-
all_machines += "\n#{machine_section}"
|
174
|
-
end
|
175
|
-
|
176
|
-
sources = {
|
177
|
-
:provider_section => provider_parent_string,
|
178
|
-
:basebox_path => @vm["basebox"],
|
179
|
-
:box_name => "zergling_#{@name}_#{@vm["driver"]["providertype"]}",
|
180
|
-
:vm_defines => all_machines
|
181
|
-
}
|
182
|
-
full_template = Erbalize.erbalize_hash(main_template, sources)
|
183
|
-
|
184
|
-
# write the file
|
185
|
-
puts ("Writing #{File.join("#{Dir.pwd}", ".hive", "driver", @vm["driver"]["drivertype"], @name, "Vagrantfile")}...")
|
186
|
-
FileUtils.mkdir_p(File.join("#{Dir.pwd}", ".hive", "driver", @vm["driver"]["drivertype"], @name))
|
187
|
-
File.open(File.join("#{Dir.pwd}", ".hive", "driver", @vm["driver"]["drivertype"], @name, "Vagrantfile"), 'w') { |file| file.write(full_template) }
|
188
|
-
end
|
189
|
-
end
|
190
|
-
end
|