zergrush 0.0.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 +7 -0
- data/.gitignore +2 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +55 -0
- data/LICENSE.txt +22 -0
- data/Rakefile +1 -0
- data/bin/zerg +3 -0
- data/data/driver/vagrant/bridging.template +1 -0
- data/data/driver/vagrant/hostonly.template +1 -0
- data/data/driver/vagrant/machine.template +22 -0
- data/data/driver/vagrant/main.template +11 -0
- data/data/driver/vagrant/provider.template +3 -0
- data/data/ke.schema +325 -0
- data/features/hive.feature +227 -0
- data/features/support/setup.rb +4 -0
- data/features/task.feature +31 -0
- data/lib/zerg.rb +30 -0
- data/lib/zerg/cli.rb +85 -0
- data/lib/zerg/driver_renderer.rb +190 -0
- data/lib/zerg/generators/hivegen.rb +63 -0
- data/lib/zerg/generators/task/awstemplate.ke +28 -0
- data/lib/zerg/generators/task/template.ke +28 -0
- data/lib/zerg/hive.rb +145 -0
- data/lib/zerg/runner.rb +232 -0
- data/lib/zerg/version.rb +26 -0
- data/spec/zerg_spec.rb +5 -0
- data/zerg.gemspec +31 -0
- metadata +198 -0
@@ -0,0 +1,63 @@
|
|
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 'thor/group'
|
25
|
+
module Zerg
|
26
|
+
module Generators
|
27
|
+
class HiveGen < Thor::Group
|
28
|
+
include Thor::Actions
|
29
|
+
|
30
|
+
class_option :force, :type => :boolean
|
31
|
+
|
32
|
+
def self.source_root
|
33
|
+
File.join(File.dirname(__FILE__), "task")
|
34
|
+
end
|
35
|
+
|
36
|
+
def create_hive
|
37
|
+
load_path = (ENV['HIVE_CWD'] == nil) ? File.join("#{Dir.pwd}", ".hive") : File.join("#{ENV['HIVE_CWD']}", ".hive")
|
38
|
+
empty_directory "#{File.join(load_path, "driver")}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def copy_sample_task
|
42
|
+
load_path = (ENV['HIVE_CWD'] == nil) ? File.join("#{Dir.pwd}", ".hive") : File.join("#{ENV['HIVE_CWD']}", ".hive")
|
43
|
+
opts = {
|
44
|
+
:instances => 3,
|
45
|
+
:drivertype => "vagrant",
|
46
|
+
:providertype => "virtualbox",
|
47
|
+
:baseboxpath => "http://files.vagrantup.com/precise32.box",
|
48
|
+
:privatenetwork => true
|
49
|
+
}
|
50
|
+
template("template.ke", "#{File.join(load_path, "helloworld.ke")}", opts)
|
51
|
+
|
52
|
+
opts = {
|
53
|
+
:instances => 3,
|
54
|
+
:drivertype => "vagrant",
|
55
|
+
:providertype => "aws",
|
56
|
+
:baseboxpath => "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box",
|
57
|
+
:privatenetwork => false
|
58
|
+
}
|
59
|
+
template("awstemplate.ke", "#{File.join(load_path, "helloaws.ke")}", opts)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
{
|
2
|
+
"instances": <%= config[:instances] %>,
|
3
|
+
"tasks": [
|
4
|
+
{
|
5
|
+
"type": "shell",
|
6
|
+
"inline": "echo \"ZERG RUSH PRIME!\""
|
7
|
+
}
|
8
|
+
],
|
9
|
+
"vm": {
|
10
|
+
"driver": {
|
11
|
+
"drivertype": "<%= config[:drivertype] %>",
|
12
|
+
"providertype": "<%= config[:providertype] %>",
|
13
|
+
"provider_options": [
|
14
|
+
"<%= config[:providertype] %>.instance_type = 't1.micro'",
|
15
|
+
"<%= config[:providertype] %>.access_key_id = \"#{ENV['AWS_ACCESS_KEY_ID']}\"",
|
16
|
+
"<%= config[:providertype] %>.secret_access_key = \"#{ENV['AWS_SECRET_ACCESS_KEY']}\"",
|
17
|
+
"<%= config[:providertype] %>.keypair_name = \"#{ENV['AWS_KEY_PAIR']}\"",
|
18
|
+
"<%= config[:providertype] %>.ami = 'ami-3fec7956'",
|
19
|
+
"<%= config[:providertype] %>.region = 'us-east-1'",
|
20
|
+
"<%= config[:providertype] %>.security_groups = [ \"#{ENV['AWS_SECURITY_GROUP']}\" ]",
|
21
|
+
"override.ssh.username = 'ubuntu'",
|
22
|
+
"override.ssh.private_key_path = \"#{ENV['AWS_PRIVATE_KEY_PATH']}\""
|
23
|
+
]
|
24
|
+
},
|
25
|
+
"basebox": "<%= config[:baseboxpath] %>",
|
26
|
+
"private_network": <%= config[:privatenetwork] %>
|
27
|
+
}
|
28
|
+
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
{
|
2
|
+
"instances": <%= config[:instances] %>,
|
3
|
+
"tasks": [
|
4
|
+
{
|
5
|
+
"type": "shell",
|
6
|
+
"inline": "echo \"ZERG RUSH!\""
|
7
|
+
}
|
8
|
+
],
|
9
|
+
"vm": {
|
10
|
+
"driver": {
|
11
|
+
"drivertype": "<%= config[:drivertype] %>",
|
12
|
+
"providertype": "<%= config[:providertype] %>",
|
13
|
+
"provider_options": [
|
14
|
+
"<%= config[:providertype] %>.gui = false",
|
15
|
+
"<%= config[:providertype] %>.memory = 256",
|
16
|
+
"# adjust for DNS weirdness in ubuntu 12.04",
|
17
|
+
"<%= config[:providertype] %>.customize ['modifyvm', :id, '--natdnsproxy1', 'off']",
|
18
|
+
"<%= config[:providertype] %>.customize ['modifyvm', :id, '--natdnshostresolver1', 'off']",
|
19
|
+
"# set virtio type on the NIC driver. Better performance for large traffic bursts",
|
20
|
+
"<%= config[:providertype] %>.customize ['modifyvm', :id, '--nictype1', 'virtio']",
|
21
|
+
"<%= config[:providertype] %>.customize ['modifyvm', :id, '--nictype2', 'virtio']",
|
22
|
+
"<%= config[:providertype] %>.customize ['modifyvm', :id, '--nictype3', 'virtio']"
|
23
|
+
]
|
24
|
+
},
|
25
|
+
"basebox": "<%= config[:baseboxpath] %>",
|
26
|
+
"private_network": <%= config[:privatenetwork] %>
|
27
|
+
}
|
28
|
+
}
|
data/lib/zerg/hive.rb
ADDED
@@ -0,0 +1,145 @@
|
|
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 'json'
|
25
|
+
require 'awesome_print'
|
26
|
+
require 'json-schema'
|
27
|
+
require 'fileutils'
|
28
|
+
require 'singleton'
|
29
|
+
require 'highline/import'
|
30
|
+
|
31
|
+
module Zerg
|
32
|
+
class Hive
|
33
|
+
include Singleton
|
34
|
+
attr_reader :hive
|
35
|
+
|
36
|
+
def loaded
|
37
|
+
@loaded || false
|
38
|
+
end
|
39
|
+
|
40
|
+
def load
|
41
|
+
if loaded
|
42
|
+
return
|
43
|
+
end
|
44
|
+
|
45
|
+
load_path = (ENV['HIVE_CWD'] == nil) ? File.join("#{Dir.pwd}", ".hive") : File.join("#{ENV['HIVE_CWD']}", ".hive")
|
46
|
+
abort("ERROR: '.hive' not found at #{load_path}. Run 'zerg init', change HIVE_CWD or run zerg from a different path.") unless File.directory?(load_path)
|
47
|
+
|
48
|
+
# load all .ke files into one big hash
|
49
|
+
@hive = Hash.new
|
50
|
+
Dir.glob(File.join("#{load_path}", "*.ke")) do |ke_file|
|
51
|
+
# do work on files ending in .rb in the desired directory
|
52
|
+
begin
|
53
|
+
ke_file_hash = JSON.parse( IO.read(ke_file) )
|
54
|
+
@hive[File.basename(ke_file, ".ke")] = ke_file_hash
|
55
|
+
rescue JSON::ParserError
|
56
|
+
abort("ERROR: Could not parse #{ke_file}. Likely invalid JSON.")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
@loaded = true
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.list
|
64
|
+
instance.load
|
65
|
+
|
66
|
+
# iterate over hive configs and print out the names
|
67
|
+
puts "Current hive tasks are:"
|
68
|
+
|
69
|
+
if instance.loaded == false
|
70
|
+
puts "No hive loaded!"
|
71
|
+
puts "FAILURE!"
|
72
|
+
return
|
73
|
+
end
|
74
|
+
|
75
|
+
if instance.hive.empty?()
|
76
|
+
puts "No tasks defined in hive."
|
77
|
+
return
|
78
|
+
end
|
79
|
+
|
80
|
+
puts "#{instance.hive.length} tasks in current hive:"
|
81
|
+
puts "#{instance.hive.keys.ai}"
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.verify
|
85
|
+
load_path = (ENV['HIVE_CWD'] == nil) ? File.join("#{Dir.pwd}", ".hive") : File.join("#{ENV['HIVE_CWD']}", ".hive")
|
86
|
+
abort("ERROR: '.hive' not found at #{load_path}. Run 'zerg init', change HIVE_CWD or run zerg from a different path.") unless File.directory?(load_path)
|
87
|
+
|
88
|
+
Dir.glob(File.join("#{load_path}", "*.ke")) do |ke_file|
|
89
|
+
begin
|
90
|
+
ke_file_hash = JSON.parse( IO.read(ke_file) )
|
91
|
+
|
92
|
+
# verify against schema.
|
93
|
+
errors = JSON::Validator.fully_validate(File.join("#{File.dirname(__FILE__)}", "../../data/ke.schema"), ke_file_hash, :errors_as_objects => true)
|
94
|
+
unless errors.empty?
|
95
|
+
abort("ERROR: #{ke_file} failed validation. Errors: #{errors.ai}")
|
96
|
+
end
|
97
|
+
rescue JSON::ParserError => err
|
98
|
+
abort("ERROR: Could not parse #{ke_file}. Likely invalid JSON.")
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
puts "SUCCESS!"
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.import(file, force)
|
106
|
+
load_path = (ENV['HIVE_CWD'] == nil) ? File.join("#{Dir.pwd}", ".hive") : File.join("#{ENV['HIVE_CWD']}", ".hive")
|
107
|
+
abort("ERROR: '.hive' not found at #{load_path}. Run 'zerg init', change HIVE_CWD or run zerg from a different path.") unless File.directory?(load_path)
|
108
|
+
abort("ERROR: '#{file}' not found!") unless File.exist?(file)
|
109
|
+
abort("ERROR: '#{File.basename(file)}' already exists in hive!") unless !File.exist?(File.join(load_path, File.basename(file))) || force == true
|
110
|
+
|
111
|
+
# check the file against schema.
|
112
|
+
begin
|
113
|
+
ke_file_hash = JSON.parse( IO.read(file) )
|
114
|
+
errors = JSON::Validator.fully_validate(File.join("#{File.dirname(__FILE__)}", "../../data/ke.schema"), ke_file_hash, :errors_as_objects => true)
|
115
|
+
abort("ERROR: #{file} failed validation. Errors: #{errors.ai}") unless errors.empty?
|
116
|
+
|
117
|
+
FileUtils.cp(file, File.join(load_path, File.basename(file)))
|
118
|
+
rescue JSON::ParserError => err
|
119
|
+
abort("ERROR: Could not parse #{file}. Likely invalid JSON.")
|
120
|
+
end
|
121
|
+
puts "SUCCESS!"
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.remove(taskname, force)
|
125
|
+
load_path = (ENV['HIVE_CWD'] == nil) ? File.join("#{Dir.pwd}", ".hive") : File.join("#{ENV['HIVE_CWD']}", ".hive")
|
126
|
+
abort("ERROR: '.hive' not found at #{load_path}. Run 'zerg init', change HIVE_CWD or run zerg from a different path.") unless File.directory?(load_path)
|
127
|
+
abort("ERROR: '#{taskname}' not found!") unless File.exist?(File.join(load_path, "#{taskname}.ke"))
|
128
|
+
|
129
|
+
# check the file against schema.
|
130
|
+
taskfile = File.join(load_path, "#{taskname}.ke")
|
131
|
+
|
132
|
+
agreed = true
|
133
|
+
if force != true
|
134
|
+
agreed = agree("Remove task #{taskname}?")
|
135
|
+
end
|
136
|
+
|
137
|
+
abort("Cancelled!") unless agreed == true
|
138
|
+
|
139
|
+
FileUtils.rm_rf(File.join(load_path, "driver", taskname))
|
140
|
+
FileUtils.rm(File.join(load_path, "#{taskname}.ke"))
|
141
|
+
|
142
|
+
puts "SUCCESS!"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
data/lib/zerg/runner.rb
ADDED
@@ -0,0 +1,232 @@
|
|
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 'rbconfig'
|
28
|
+
|
29
|
+
module Zerg
|
30
|
+
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 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
|
+
run(taskname, task["vm"]["driver"]["drivertype"], task["vm"]["driver"]["providertype"], task["instances"], debug)
|
99
|
+
end
|
100
|
+
|
101
|
+
def cleanup(taskname, task, debug)
|
102
|
+
abort("ERROR: Vagrant not installed!") unless which("vagrant") != nil
|
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 run(taskname, driver, provider, instances, debug)
|
140
|
+
# TODO: generalize to multiple drivers
|
141
|
+
abort("ERROR: Vagrant not installed!") unless which("vagrant") != nil
|
142
|
+
|
143
|
+
check_provider(driver, provider)
|
144
|
+
|
145
|
+
debug_string = (debug == true) ? " --debug" : ""
|
146
|
+
|
147
|
+
# bring up all of the VMs first.
|
148
|
+
puts("Starting vagrant in #{File.join("#{Dir.pwd}", ".hive", "driver", driver, taskname)}")
|
149
|
+
for index in 0..instances - 1
|
150
|
+
create_pid = Process.spawn(
|
151
|
+
{
|
152
|
+
"VAGRANT_CWD" => File.join("#{Dir.pwd}", ".hive", "driver", driver, taskname)
|
153
|
+
},
|
154
|
+
"vagrant up zergling_#{index} --no-provision --provider=#{provider}#{debug_string}")
|
155
|
+
Process.wait(create_pid)
|
156
|
+
|
157
|
+
if $?.exitstatus != 0
|
158
|
+
puts "ERROR: vagrant failed while creating one of the VMs. Will clean task #{taskname}:"
|
159
|
+
self.class.clean(taskname, debug)
|
160
|
+
abort("ERROR: vagrant failed!")
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
puts("Running tasks in vagrant virtual machines...")
|
165
|
+
# and provision them all at once (sort of)
|
166
|
+
provisioners = Array.new
|
167
|
+
provision_pid = nil
|
168
|
+
for index in 0..instances - 1
|
169
|
+
provision_pid = Process.spawn(
|
170
|
+
{
|
171
|
+
"VAGRANT_CWD" => File.join("#{Dir.pwd}", ".hive", "driver", driver, taskname),
|
172
|
+
"VAGRANT_DEFAULT_PROVIDER" => "#{provider}"
|
173
|
+
},
|
174
|
+
"vagrant provision zergling_#{index}#{debug_string}")
|
175
|
+
provisioners.push({:name => "zergling_#{index}", :pid => provision_pid})
|
176
|
+
end
|
177
|
+
|
178
|
+
# wait for everything to finish...
|
179
|
+
errors = Array.new
|
180
|
+
lock = Mutex.new
|
181
|
+
provisioners.each { |provisioner|
|
182
|
+
Thread.new {
|
183
|
+
Process.wait(provisioner[:pid]);
|
184
|
+
lock.synchronize do
|
185
|
+
errors.push(provisioner[:name]) unless $?.exitstatus == 0
|
186
|
+
end
|
187
|
+
}.join
|
188
|
+
}
|
189
|
+
|
190
|
+
puts("DONE! Halting all vagrant virtual machines...")
|
191
|
+
# halt all machines
|
192
|
+
halt_pid = nil
|
193
|
+
for index in 0..instances - 1
|
194
|
+
halt_pid = Process.spawn(
|
195
|
+
{
|
196
|
+
"VAGRANT_CWD" => File.join("#{Dir.pwd}", ".hive", "driver", driver, taskname),
|
197
|
+
"VAGRANT_DEFAULT_PROVIDER" => "#{provider}"
|
198
|
+
},
|
199
|
+
"vagrant halt zergling_#{index}#{debug_string}")
|
200
|
+
Process.wait(halt_pid)
|
201
|
+
abort("ERROR: vagrant halt failed on machine zergling_#{index}!") unless $?.exitstatus == 0
|
202
|
+
end
|
203
|
+
|
204
|
+
abort("ERROR: Finished with errors in: #{errors.to_s}") unless errors.length == 0
|
205
|
+
puts("SUCCESS!")
|
206
|
+
end
|
207
|
+
|
208
|
+
def self.rush(task, debug)
|
209
|
+
# load the hive first
|
210
|
+
Zerg::Hive.instance.load
|
211
|
+
|
212
|
+
puts "Loaded hive. Looking for task #{task}..."
|
213
|
+
abort("ERROR: Task #{task} not found in current hive!") unless Zerg::Hive.instance.hive.has_key?(task)
|
214
|
+
|
215
|
+
# grab the current task hash and parse it out
|
216
|
+
runner = Runner.new
|
217
|
+
runner.process(task, Zerg::Hive.instance.hive[task], debug);
|
218
|
+
end
|
219
|
+
|
220
|
+
def self.clean(task, debug)
|
221
|
+
# load the hive first
|
222
|
+
Zerg::Hive.instance.load
|
223
|
+
|
224
|
+
puts "Loaded hive. Looking for task #{task}..."
|
225
|
+
abort("ERROR: Task #{task} not found in current hive!") unless Zerg::Hive.instance.hive.has_key?(task)
|
226
|
+
|
227
|
+
runner = Runner.new
|
228
|
+
runner.cleanup(task, Zerg::Hive.instance.hive[task], debug);
|
229
|
+
puts("SUCCESS!")
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|