zergrush 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|