the-maestro 0.3.9 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +22 -6
- data/VERSION +1 -1
- data/lib/maestro.rb +39 -18
- data/lib/maestro/cloud.rb +2 -2
- data/lib/maestro/node.rb +1 -1
- data/lib/maestro/operating_system/cent_os.rb +2 -2
- data/lib/maestro/operating_system/debian.rb +2 -2
- data/lib/maestro/operating_system/fedora.rb +2 -2
- data/lib/maestro/operating_system/ubuntu.rb +4 -4
- data/lib/maestro/railtie.rb +10 -0
- data/test/integration/helper.rb +0 -1
- data/test/unit/test_invalid_mode.rb +2 -1
- data/test/unit/test_maestro.rb +53 -1
- data/test/unit/test_rails_mode.rb +117 -11
- data/test/unit/test_standalone_mode.rb +9 -9
- data/the-maestro.gemspec +5 -4
- metadata +96 -41
data/README.rdoc
CHANGED
@@ -12,29 +12,45 @@ Maestro currently supports the following Linux distributions:
|
|
12
12
|
Debian (5.0)
|
13
13
|
Fedora (8)
|
14
14
|
CentOS (5.4)
|
15
|
+
|
16
|
+
Maestro has been tested with the following Ruby versions (thanks {RVM}[http://rvm.beginrescueend.com]!):
|
17
|
+
|
18
|
+
MRI (1.8.7, 1.9.1, 1.9.2)
|
19
|
+
JRuby (1.5.2)
|
15
20
|
|
16
21
|
|
17
22
|
== Using Maestro with Ruby On Rails
|
18
23
|
|
19
|
-
=== Installation
|
24
|
+
=== Installation with Ruby On Rails 3
|
25
|
+
|
26
|
+
Add the following gem dependency to your Rails project's <code>Gemfile</code>:
|
27
|
+
|
28
|
+
gem 'the-maestro', '0.4.0', :require => 'maestro'
|
29
|
+
|
30
|
+
Then run the following to install the Maestro gem:
|
31
|
+
|
32
|
+
bundle install
|
33
|
+
|
34
|
+
|
35
|
+
=== Installation with Ruby On Rails 2
|
20
36
|
|
21
37
|
Add the following gem dependency to your Rails project's <code>config/environment.rb</code> file:
|
22
38
|
|
23
39
|
Rails::Initializer.run do |config|
|
24
40
|
|
25
|
-
config.gem "the-maestro", :lib => "maestro", :version => "0.
|
41
|
+
config.gem "the-maestro", :lib => "maestro", :version => "0.4.0", :source => "http://gemcutter.org"
|
26
42
|
|
27
43
|
end
|
28
44
|
|
29
45
|
Then run the following to install the Maestro gem:
|
30
46
|
|
31
|
-
|
47
|
+
rake gems:install
|
32
48
|
|
33
49
|
You may optionally unpack Maestro into vendor/gems by running:
|
34
50
|
|
35
|
-
|
51
|
+
rake gems:unpack:dependencies
|
36
52
|
|
37
|
-
You'll interact with Maestro through custom Rake tasks that Maestro adds to your Rails project.
|
53
|
+
You'll interact with Maestro through custom Rake tasks that Maestro adds to your Rails project. Due to {this}[https://rails.lighthouseapp.com/projects/8994/tickets/59] issue in Rails 2 (fixed in Rails 3), you'll need to add this to your Rails project's Rakefile:
|
38
54
|
|
39
55
|
require 'maestro/tasks'
|
40
56
|
|
@@ -355,7 +371,7 @@ Maestro can also be used in stand alone mode, as a simple command line cloud man
|
|
355
371
|
|
356
372
|
Install the Maestro gem by running the following command:
|
357
373
|
|
358
|
-
|
374
|
+
gem install the-maestro
|
359
375
|
|
360
376
|
=== Requirements
|
361
377
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
data/lib/maestro.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
require "maestro/dsl_property"
|
2
2
|
require "find"
|
3
|
-
require "
|
3
|
+
require "fileutils"
|
4
4
|
require "maestro/cloud"
|
5
5
|
require "maestro/cloud/aws"
|
6
6
|
require "maestro/operating_system"
|
7
7
|
require "log4r"
|
8
8
|
require "log4r/configurator"
|
9
9
|
require "maestro/log4r/console_formatter"
|
10
|
+
require 'maestro/railtie' if defined?(Rails) && Rails::VERSION::MAJOR == 3
|
10
11
|
|
11
12
|
|
12
13
|
def aws_cloud(name, &block)
|
@@ -53,12 +54,12 @@ module Maestro
|
|
53
54
|
# MAESTRO_DIR/config/maestro/cookbooks
|
54
55
|
# MAESTRO_DIR/config/maestro/roles
|
55
56
|
def self.create_config_dirs
|
56
|
-
if
|
57
|
+
if rails?
|
57
58
|
create_configs(rails_config_dir)
|
58
59
|
elsif ENV.has_key? MAESTRO_DIR_ENV_VAR
|
59
60
|
create_configs(standalone_config_dir)
|
60
61
|
else
|
61
|
-
raise "Maestro not configured correctly. Either RAILS_ROOT or ENV['#{MAESTRO_DIR_ENV_VAR}'] must be defined"
|
62
|
+
raise "Maestro not configured correctly. Either RAILS_ROOT, Rails.root, or ENV['#{MAESTRO_DIR_ENV_VAR}'] must be defined"
|
62
63
|
end
|
63
64
|
end
|
64
65
|
|
@@ -75,12 +76,12 @@ module Maestro
|
|
75
76
|
# MAESTRO_DIR/log/maestro
|
76
77
|
# MAESTRO_DIR/log/maestro/clouds
|
77
78
|
def self.create_log_dirs
|
78
|
-
if
|
79
|
+
if rails?
|
79
80
|
create_logs(rails_log_dir)
|
80
81
|
elsif ENV.has_key? MAESTRO_DIR_ENV_VAR
|
81
82
|
create_logs(standalone_log_dir)
|
82
83
|
else
|
83
|
-
raise "Maestro not configured correctly. Either RAILS_ROOT or ENV['#{MAESTRO_DIR_ENV_VAR}'] must be defined"
|
84
|
+
raise "Maestro not configured correctly. Either RAILS_ROOT, Rails.root, or ENV['#{MAESTRO_DIR_ENV_VAR}'] must be defined"
|
84
85
|
end
|
85
86
|
end
|
86
87
|
|
@@ -88,45 +89,45 @@ module Maestro
|
|
88
89
|
# * element[0] boolean indicating whether your maestro configs are valid
|
89
90
|
# * element[1] Array of Strings containing a report of the validation
|
90
91
|
def self.validate_configs
|
91
|
-
if
|
92
|
+
if rails?
|
92
93
|
validate_rails_config
|
93
94
|
elsif ENV.has_key? MAESTRO_DIR_ENV_VAR
|
94
95
|
validate_standalone_config
|
95
96
|
else
|
96
|
-
return [false, ["Maestro not configured correctly. Either RAILS_ROOT or ENV['#{MAESTRO_DIR_ENV_VAR}'] must be defined"]]
|
97
|
+
return [false, ["Maestro not configured correctly. Either RAILS_ROOT, Rails.root, or ENV['#{MAESTRO_DIR_ENV_VAR}'] must be defined"]]
|
97
98
|
end
|
98
99
|
end
|
99
100
|
|
100
101
|
# Returns a Hash of Clouds defined in the Maestro clouds configuration directory
|
101
102
|
def self.clouds
|
102
|
-
if
|
103
|
+
if rails?
|
103
104
|
get_clouds(clouds_config_dir(rails_maestro_config_dir))
|
104
105
|
elsif ENV.has_key? MAESTRO_DIR_ENV_VAR
|
105
106
|
get_clouds(clouds_config_dir(standalone_maestro_config_dir))
|
106
107
|
else
|
107
|
-
raise "Maestro not configured correctly. Either RAILS_ROOT or ENV['#{MAESTRO_DIR_ENV_VAR}'] must be defined"
|
108
|
+
raise "Maestro not configured correctly. Either RAILS_ROOT, Rails.root, or ENV['#{MAESTRO_DIR_ENV_VAR}'] must be defined"
|
108
109
|
end
|
109
110
|
end
|
110
111
|
|
111
112
|
# Returns the top level log directory
|
112
113
|
def self.log_directory
|
113
|
-
if
|
114
|
+
if rails?
|
114
115
|
rails_log_dir
|
115
116
|
elsif ENV.has_key? MAESTRO_DIR_ENV_VAR
|
116
117
|
standalone_log_dir
|
117
118
|
else
|
118
|
-
raise "Maestro not configured correctly. Either RAILS_ROOT or ENV['#{MAESTRO_DIR_ENV_VAR}'] must be defined"
|
119
|
+
raise "Maestro not configured correctly. Either RAILS_ROOT, Rails.root, or ENV['#{MAESTRO_DIR_ENV_VAR}'] must be defined"
|
119
120
|
end
|
120
121
|
end
|
121
122
|
|
122
123
|
# Returns the maestro log directory
|
123
124
|
def self.maestro_log_directory
|
124
|
-
if
|
125
|
+
if rails?
|
125
126
|
rails_log_dir + "/maestro"
|
126
127
|
elsif ENV.has_key? MAESTRO_DIR_ENV_VAR
|
127
128
|
standalone_log_dir + "/maestro"
|
128
129
|
else
|
129
|
-
raise "Maestro not configured correctly. Either RAILS_ROOT or ENV['#{MAESTRO_DIR_ENV_VAR}'] must be defined"
|
130
|
+
raise "Maestro not configured correctly. Either RAILS_ROOT, Rails.root, or ENV['#{MAESTRO_DIR_ENV_VAR}'] must be defined"
|
130
131
|
end
|
131
132
|
end
|
132
133
|
|
@@ -137,12 +138,12 @@ module Maestro
|
|
137
138
|
require 'archive/tar/minitar'
|
138
139
|
|
139
140
|
dir = nil
|
140
|
-
if
|
141
|
+
if rails?
|
141
142
|
dir = rails_maestro_config_dir
|
142
143
|
elsif ENV.has_key? MAESTRO_DIR_ENV_VAR
|
143
144
|
dir = standalone_maestro_config_dir
|
144
145
|
else
|
145
|
-
raise "Maestro not configured correctly. Either RAILS_ROOT or ENV['#{MAESTRO_DIR_ENV_VAR}'] must be defined"
|
146
|
+
raise "Maestro not configured correctly. Either RAILS_ROOT, Rails.root, or ENV['#{MAESTRO_DIR_ENV_VAR}'] must be defined"
|
146
147
|
end
|
147
148
|
temp_file = Dir.tmpdir + "/" + MAESTRO_CHEF_ARCHIVE
|
148
149
|
File.delete(temp_file) if File.exist?(temp_file)
|
@@ -171,6 +172,16 @@ module Maestro
|
|
171
172
|
|
172
173
|
private
|
173
174
|
|
175
|
+
# Rails environment detected?
|
176
|
+
def self.rails?
|
177
|
+
defined?(RAILS_ROOT) || (defined?(Rails) && defined?(Rails.root) && Rails.root)
|
178
|
+
end
|
179
|
+
|
180
|
+
# Rails 3 environment detected?
|
181
|
+
def self.rails3?
|
182
|
+
defined?(Rails) && Rails::VERSION::MAJOR == 3
|
183
|
+
end
|
184
|
+
|
174
185
|
# Creates the Maestro config directory structure in the given directory
|
175
186
|
#
|
176
187
|
# - dir: The base directory in which to create the maestro config directory structure
|
@@ -292,16 +303,25 @@ module Maestro
|
|
292
303
|
return [valid, error_messages]
|
293
304
|
end
|
294
305
|
|
306
|
+
def self.rails_root
|
307
|
+
root = if defined?(Rails.root) && Rails.root
|
308
|
+
Rails.root
|
309
|
+
else
|
310
|
+
RAILS_ROOT
|
311
|
+
end
|
312
|
+
root
|
313
|
+
end
|
314
|
+
|
295
315
|
def self.rails_config_dir
|
296
|
-
"#{
|
316
|
+
"#{rails_root}/config"
|
297
317
|
end
|
298
318
|
|
299
319
|
def self.rails_log_dir
|
300
|
-
"#{
|
320
|
+
"#{rails_root}/log"
|
301
321
|
end
|
302
322
|
|
303
323
|
def self.rails_maestro_config_dir
|
304
|
-
"#{
|
324
|
+
"#{rails_root}#{MAESTRO_RAILS_CONFIG_DIRECTORY}"
|
305
325
|
end
|
306
326
|
|
307
327
|
def self.standalone_maestro_config_dir
|
@@ -344,6 +364,7 @@ module Maestro
|
|
344
364
|
# Returns and array of all Cloud files found in clouds_directory
|
345
365
|
def self.get_cloud_config_files(clouds_directory)
|
346
366
|
config_files = []
|
367
|
+
return config_files if !File.exists?(clouds_directory)
|
347
368
|
Find.find(clouds_directory) do |path|
|
348
369
|
if FileTest.file?(path) && (File.extname(path).eql?(".rb"))
|
349
370
|
config_files << path
|
data/lib/maestro/cloud.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require "
|
1
|
+
require "fileutils"
|
2
2
|
require "maestro/role"
|
3
3
|
require "maestro/node"
|
4
4
|
require 'maestro/validator'
|
@@ -321,7 +321,7 @@ module Maestro
|
|
321
321
|
outputter = Log4r::FileOutputter.new("#{@name}-file", :formatter => FileFormatter.new, :filename => cloud_log_file, :truncate => false)
|
322
322
|
@logger.add(outputter)
|
323
323
|
rescue RuntimeError => rerr
|
324
|
-
if !rerr.message.eql?("Maestro not configured correctly. Either RAILS_ROOT or ENV['MAESTRO_DIR'] must be defined")
|
324
|
+
if !rerr.message.eql?("Maestro not configured correctly. Either RAILS_ROOT, Rails.root, or ENV['MAESTRO_DIR'] must be defined")
|
325
325
|
@logger.error "Unexpected Error"
|
326
326
|
@logger.error rerr
|
327
327
|
end
|
data/lib/maestro/node.rb
CHANGED
@@ -74,7 +74,7 @@ module Maestro
|
|
74
74
|
@logger.add(outputter)
|
75
75
|
end
|
76
76
|
rescue RuntimeError => rerr
|
77
|
-
if !rerr.message.eql?("Maestro not configured correctly. Either RAILS_ROOT or ENV['MAESTRO_DIR'] must be defined")
|
77
|
+
if !rerr.message.eql?("Maestro not configured correctly. Either RAILS_ROOT, Rails.root, or ENV['MAESTRO_DIR'] must be defined")
|
78
78
|
@logger.error "Unexpected Error"
|
79
79
|
@logger.error rerr
|
80
80
|
end
|
@@ -15,8 +15,8 @@ module Maestro
|
|
15
15
|
"sudo rm /usr/local/src/rubygems-1.3.6.tgz",
|
16
16
|
"sudo gem sources -a http://gems.opscode.com",
|
17
17
|
"sudo gem install rake --no-rdoc --no-ri",
|
18
|
-
"sudo gem install chef --no-rdoc --no-ri --version '= 0.9.
|
19
|
-
"sudo ln -sfv $(gem environment gemdir)/gems/chef-0.9.
|
18
|
+
"sudo gem install chef --no-rdoc --no-ri --version '= 0.9.8'",
|
19
|
+
"sudo ln -sfv $(gem environment gemdir)/gems/chef-0.9.8/bin/chef-solo /usr/bin/chef-solo"]
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -18,8 +18,8 @@ module Maestro
|
|
18
18
|
"sudo ln -sfv /usr/bin/gem1.8 /usr/bin/gem",
|
19
19
|
"sudo gem sources -a http://gems.opscode.com",
|
20
20
|
"sudo gem install rake --no-rdoc --no-ri",
|
21
|
-
"sudo gem install chef --no-rdoc --no-ri --version '= 0.9.
|
22
|
-
"sudo ln -sfv $(gem environment gemdir)/gems/chef-0.9.
|
21
|
+
"sudo gem install chef --no-rdoc --no-ri --version '= 0.9.8'",
|
22
|
+
"sudo ln -sfv $(gem environment gemdir)/gems/chef-0.9.8/bin/chef-solo /usr/bin/chef-solo"]
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
@@ -15,8 +15,8 @@ module Maestro
|
|
15
15
|
"sudo rm /usr/local/src/rubygems-1.3.6.tgz",
|
16
16
|
"sudo gem sources -a http://gems.opscode.com",
|
17
17
|
"sudo gem install rake --no-rdoc --no-ri",
|
18
|
-
"sudo gem install chef --no-rdoc --no-ri --version '= 0.9.
|
19
|
-
"sudo ln -sfv $(gem environment gemdir)/gems/chef-0.9.
|
18
|
+
"sudo gem install chef --no-rdoc --no-ri --version '= 0.9.8'",
|
19
|
+
"sudo ln -sfv $(gem environment gemdir)/gems/chef-0.9.8/bin/chef-solo /usr/bin/chef-solo"]
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -16,8 +16,8 @@ module Maestro
|
|
16
16
|
"sudo ln -sfv /usr/bin/gem1.8 /usr/bin/gem",
|
17
17
|
"sudo gem sources -a http://gems.opscode.com",
|
18
18
|
"sudo gem install rake --no-rdoc --no-ri",
|
19
|
-
"sudo gem install chef --no-rdoc --no-ri --version '= 0.9.
|
20
|
-
"sudo ln -sfv $(gem environment gemdir)/gems/chef-0.9.
|
19
|
+
"sudo gem install chef --no-rdoc --no-ri --version '= 0.9.8'",
|
20
|
+
"sudo ln -sfv $(gem environment gemdir)/gems/chef-0.9.8/bin/chef-solo /usr/bin/chef-solo"]
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -38,8 +38,8 @@ module Maestro
|
|
38
38
|
"sudo ln -sfv /usr/bin/gem1.8 /usr/bin/gem",
|
39
39
|
"sudo gem sources -a http://gems.opscode.com",
|
40
40
|
"sudo gem install rake --no-rdoc --no-ri",
|
41
|
-
"sudo gem install chef --no-rdoc --no-ri --version '= 0.9.
|
42
|
-
"sudo ln -sfv $(gem environment gemdir)/gems/chef-0.9.
|
41
|
+
"sudo gem install chef --no-rdoc --no-ri --version '= 0.9.8'",
|
42
|
+
"sudo ln -sfv $(gem environment gemdir)/gems/chef-0.9.8/bin/chef-solo /usr/bin/chef-solo"]
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
data/test/integration/helper.rb
CHANGED
@@ -5,7 +5,8 @@ class TestInvalidMode < Test::Unit::TestCase
|
|
5
5
|
|
6
6
|
should "be invalid due to no rails or standalone" do
|
7
7
|
result = Maestro.validate_configs
|
8
|
-
assert !result[0]
|
8
|
+
assert !result[0]
|
9
|
+
assert result[1].any? {|message| !message.index("Maestro not configured correctly.").nil? }
|
9
10
|
end
|
10
11
|
|
11
12
|
end
|
data/test/unit/test_maestro.rb
CHANGED
@@ -5,7 +5,7 @@ class TestMaestro < Test::Unit::TestCase
|
|
5
5
|
|
6
6
|
context "Maestro" do
|
7
7
|
|
8
|
-
context "Rails mode" do
|
8
|
+
context "Rails 2 mode" do
|
9
9
|
setup do
|
10
10
|
Object.const_set("RAILS_ROOT", File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'rails'))
|
11
11
|
end
|
@@ -33,10 +33,59 @@ class TestMaestro < Test::Unit::TestCase
|
|
33
33
|
assert_log_directories_do_not_exist("#{RAILS_ROOT}/log")
|
34
34
|
end
|
35
35
|
end
|
36
|
+
|
37
|
+
should "get clouds" do
|
38
|
+
assert_nothing_raised do
|
39
|
+
Maestro.create_config_dirs
|
40
|
+
Maestro.clouds
|
41
|
+
delete_config_directories("#{RAILS_ROOT}/config")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
context "Rails 3 mode" do
|
48
|
+
setup do
|
49
|
+
class ::Rails
|
50
|
+
def self.root
|
51
|
+
File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'rails')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
teardown do
|
57
|
+
class ::Rails
|
58
|
+
class <<self
|
59
|
+
undef :root if defined?(Rails.root)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
should "create config dirs" do
|
65
|
+
assert_nothing_raised do
|
66
|
+
assert_config_directories_do_not_exist("#{Rails.root}/config")
|
67
|
+
Maestro.create_config_dirs
|
68
|
+
assert_config_directories_exist("#{Rails.root}/config")
|
69
|
+
delete_config_directories("#{Rails.root}/config")
|
70
|
+
assert_config_directories_do_not_exist("#{Rails.root}/config")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
should "create log dirs" do
|
75
|
+
assert_nothing_raised do
|
76
|
+
assert_log_directories_do_not_exist("#{Rails.root}/log")
|
77
|
+
Maestro.create_log_dirs
|
78
|
+
assert_log_directories_exist("#{Rails.root}/log")
|
79
|
+
delete_log_directories("#{Rails.root}/log")
|
80
|
+
assert_log_directories_do_not_exist("#{Rails.root}/log")
|
81
|
+
end
|
82
|
+
end
|
36
83
|
|
37
84
|
should "get clouds" do
|
38
85
|
assert_nothing_raised do
|
86
|
+
Maestro.create_config_dirs
|
39
87
|
Maestro.clouds
|
88
|
+
delete_config_directories("#{Rails.root}/config")
|
40
89
|
end
|
41
90
|
end
|
42
91
|
end
|
@@ -75,7 +124,10 @@ class TestMaestro < Test::Unit::TestCase
|
|
75
124
|
|
76
125
|
should "get clouds" do
|
77
126
|
assert_nothing_raised do
|
127
|
+
base_dir = ENV[Maestro::MAESTRO_DIR_ENV_VAR]
|
128
|
+
Maestro.create_config_dirs
|
78
129
|
Maestro.clouds
|
130
|
+
delete_config_directories("#{base_dir}/config")
|
79
131
|
end
|
80
132
|
end
|
81
133
|
end
|
@@ -3,14 +3,14 @@ require 'helper'
|
|
3
3
|
# Unit tests for Rails mode
|
4
4
|
class TestRailsMode < Test::Unit::TestCase
|
5
5
|
|
6
|
-
context "
|
6
|
+
context "Rails2 mode" do
|
7
7
|
teardown do
|
8
8
|
Object.send(:remove_const, "RAILS_ROOT")
|
9
9
|
end
|
10
10
|
|
11
11
|
should "be invalid due to missing RAILS_ROOT" do
|
12
12
|
result = Maestro.validate_configs
|
13
|
-
assert !result[0]
|
13
|
+
assert !result[0]
|
14
14
|
assert result[1].any? {|message| !message.index("Maestro not configured correctly").nil? }
|
15
15
|
# so teardown doesn't fail
|
16
16
|
Object.const_set("RAILS_ROOT", "blah")
|
@@ -19,59 +19,165 @@ class TestRailsMode < Test::Unit::TestCase
|
|
19
19
|
should "be invalid due to missing maestro directory" do
|
20
20
|
Object.const_set("RAILS_ROOT", File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'invalid-missing-maestro'))
|
21
21
|
result = Maestro.validate_configs
|
22
|
-
assert !result[0]
|
22
|
+
assert !result[0]
|
23
23
|
assert result[1].any? {|message| !message.index("Maestro config directory does not exist").nil? }
|
24
24
|
end
|
25
25
|
|
26
26
|
should "be invalid due to maestro not a directory" do
|
27
27
|
Object.const_set("RAILS_ROOT", File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'invalid-maestro-not-a-directory'))
|
28
28
|
result = Maestro.validate_configs
|
29
|
-
assert !result[0]
|
29
|
+
assert !result[0]
|
30
30
|
assert result[1].any? {|message| !message.index("Maestro config directory is not a directory").nil? }
|
31
31
|
end
|
32
32
|
|
33
33
|
should "be invalid due to missing clouds directory" do
|
34
34
|
Object.const_set("RAILS_ROOT", File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'invalid-missing-clouds'))
|
35
35
|
result = Maestro.validate_configs
|
36
|
-
assert !result[0]
|
36
|
+
assert !result[0]
|
37
37
|
assert result[1].any? {|message| !message.index("Maestro clouds config directory does not exist").nil? }
|
38
38
|
end
|
39
39
|
|
40
40
|
should "be invalid due to clouds not a directory" do
|
41
41
|
Object.const_set("RAILS_ROOT", File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'invalid-clouds-not-a-directory'))
|
42
42
|
result = Maestro.validate_configs
|
43
|
-
assert !result[0]
|
43
|
+
assert !result[0]
|
44
44
|
assert result[1].any? {|message| !message.index("Maestro clouds config directory is not a directory").nil? }
|
45
45
|
end
|
46
46
|
|
47
47
|
should "be invalid due to missing cookbooks directory" do
|
48
48
|
Object.const_set("RAILS_ROOT", File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'invalid-missing-cookbooks'))
|
49
49
|
result = Maestro.validate_configs
|
50
|
-
assert !result[0]
|
50
|
+
assert !result[0]
|
51
51
|
assert result[1].any? {|message| !message.index("Chef cookbooks directory does not exist").nil? }
|
52
52
|
end
|
53
53
|
|
54
54
|
should "be invalid due to cookbooks not a directory" do
|
55
55
|
Object.const_set("RAILS_ROOT", File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'invalid-cookbooks-not-a-directory'))
|
56
56
|
result = Maestro.validate_configs
|
57
|
-
assert !result[0]
|
57
|
+
assert !result[0]
|
58
58
|
assert result[1].any? {|message| !message.index("Chef cookbooks directory is not a directory").nil? }
|
59
59
|
end
|
60
60
|
|
61
61
|
should "be invalid due to missing roles directory" do
|
62
62
|
Object.const_set("RAILS_ROOT", File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'invalid-missing-roles'))
|
63
63
|
result = Maestro.validate_configs
|
64
|
-
assert !result[0]
|
64
|
+
assert !result[0]
|
65
65
|
assert result[1].any? {|message| !message.index("Chef roles directory does not exist").nil? }
|
66
66
|
end
|
67
67
|
|
68
68
|
should "be invalid due to roles not a directory" do
|
69
69
|
Object.const_set("RAILS_ROOT", File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'invalid-roles-not-a-directory'))
|
70
70
|
result = Maestro.validate_configs
|
71
|
-
assert !result[0]
|
71
|
+
assert !result[0]
|
72
72
|
assert result[1].any? {|message| !message.index("Chef roles directory is not a directory").nil? }
|
73
73
|
end
|
74
|
-
|
75
74
|
end
|
76
75
|
|
76
|
+
|
77
|
+
context "Rails3 mode" do
|
78
|
+
setup do
|
79
|
+
end
|
80
|
+
|
81
|
+
teardown do
|
82
|
+
class ::Rails
|
83
|
+
class <<self
|
84
|
+
undef :root if defined?(Rails.root)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
should "be invalid due to missing Rails.root" do
|
90
|
+
result = Maestro.validate_configs
|
91
|
+
assert !result[0]
|
92
|
+
assert result[1].any? {|message| !message.index("Maestro not configured correctly").nil? }
|
93
|
+
end
|
94
|
+
|
95
|
+
should "be invalid due to missing maestro directory" do
|
96
|
+
class ::Rails
|
97
|
+
def self.root
|
98
|
+
File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'invalid-missing-maestro')
|
99
|
+
end
|
100
|
+
end
|
101
|
+
result = Maestro.validate_configs
|
102
|
+
assert !result[0]
|
103
|
+
assert result[1].any? {|message| !message.index("Maestro config directory does not exist").nil? }
|
104
|
+
end
|
105
|
+
|
106
|
+
should "be invalid due to maestro not a directory" do
|
107
|
+
class ::Rails
|
108
|
+
def self.root
|
109
|
+
File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'invalid-maestro-not-a-directory')
|
110
|
+
end
|
111
|
+
end
|
112
|
+
result = Maestro.validate_configs
|
113
|
+
assert !result[0]
|
114
|
+
assert result[1].any? {|message| !message.index("Maestro config directory is not a directory").nil? }
|
115
|
+
end
|
116
|
+
|
117
|
+
should "be invalid due to missing clouds directory" do
|
118
|
+
class ::Rails
|
119
|
+
def self.root
|
120
|
+
File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'invalid-missing-clouds')
|
121
|
+
end
|
122
|
+
end
|
123
|
+
result = Maestro.validate_configs
|
124
|
+
assert !result[0]
|
125
|
+
assert result[1].any? {|message| !message.index("Maestro clouds config directory does not exist").nil? }
|
126
|
+
end
|
127
|
+
|
128
|
+
should "be invalid due to clouds not a directory" do
|
129
|
+
class ::Rails
|
130
|
+
def self.root
|
131
|
+
File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'invalid-clouds-not-a-directory')
|
132
|
+
end
|
133
|
+
end
|
134
|
+
result = Maestro.validate_configs
|
135
|
+
assert !result[0]
|
136
|
+
assert result[1].any? {|message| !message.index("Maestro clouds config directory is not a directory").nil? }
|
137
|
+
end
|
138
|
+
|
139
|
+
should "be invalid due to missing cookbooks directory" do
|
140
|
+
class ::Rails
|
141
|
+
def self.root
|
142
|
+
File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'invalid-missing-cookbooks')
|
143
|
+
end
|
144
|
+
end
|
145
|
+
result = Maestro.validate_configs
|
146
|
+
assert !result[0]
|
147
|
+
assert result[1].any? {|message| !message.index("Chef cookbooks directory does not exist").nil? }
|
148
|
+
end
|
149
|
+
|
150
|
+
should "be invalid due to cookbooks not a directory" do
|
151
|
+
class ::Rails
|
152
|
+
def self.root
|
153
|
+
File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'invalid-cookbooks-not-a-directory')
|
154
|
+
end
|
155
|
+
end
|
156
|
+
result = Maestro.validate_configs
|
157
|
+
assert !result[0]
|
158
|
+
assert result[1].any? {|message| !message.index("Chef cookbooks directory is not a directory").nil? }
|
159
|
+
end
|
160
|
+
|
161
|
+
should "be invalid due to missing roles directory" do
|
162
|
+
class ::Rails
|
163
|
+
def self.root
|
164
|
+
File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'invalid-missing-roles')
|
165
|
+
end
|
166
|
+
end
|
167
|
+
result = Maestro.validate_configs
|
168
|
+
assert !result[0]
|
169
|
+
assert result[1].any? {|message| !message.index("Chef roles directory does not exist").nil? }
|
170
|
+
end
|
171
|
+
|
172
|
+
should "be invalid due to roles not a directory" do
|
173
|
+
class ::Rails
|
174
|
+
def self.root
|
175
|
+
File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'invalid-roles-not-a-directory')
|
176
|
+
end
|
177
|
+
end
|
178
|
+
result = Maestro.validate_configs
|
179
|
+
assert !result[0]
|
180
|
+
assert result[1].any? {|message| !message.index("Chef roles directory is not a directory").nil? }
|
181
|
+
end
|
182
|
+
end
|
77
183
|
end
|
@@ -10,63 +10,63 @@ class TestStandaloneMode < Test::Unit::TestCase
|
|
10
10
|
|
11
11
|
should "be invalid due to missing maestro directory env var" do
|
12
12
|
result = Maestro.validate_configs
|
13
|
-
assert !result[0]
|
13
|
+
assert !result[0]
|
14
14
|
assert result[1].any? {|message| !message.index("Maestro not configured correctly").nil? }
|
15
15
|
end
|
16
16
|
|
17
17
|
should "be invalid due to missing maestro directory" do
|
18
18
|
ENV[Maestro::MAESTRO_DIR_ENV_VAR] = File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'invalid-missing-maestro')
|
19
19
|
result = Maestro.validate_configs
|
20
|
-
assert !result[0]
|
20
|
+
assert !result[0]
|
21
21
|
assert result[1].any? {|message| !message.index("Maestro config directory does not exist").nil? }
|
22
22
|
end
|
23
23
|
|
24
24
|
should "be invalid due to maestro not a directory" do
|
25
25
|
ENV[Maestro::MAESTRO_DIR_ENV_VAR] = File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'invalid-maestro-not-a-directory')
|
26
26
|
result = Maestro.validate_configs
|
27
|
-
assert !result[0]
|
27
|
+
assert !result[0]
|
28
28
|
assert result[1].any? {|message| !message.index("Maestro config directory is not a directory").nil? }
|
29
29
|
end
|
30
30
|
|
31
31
|
should "be invalid due to missing clouds directory" do
|
32
32
|
ENV[Maestro::MAESTRO_DIR_ENV_VAR] = File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'invalid-missing-clouds')
|
33
33
|
result = Maestro.validate_configs
|
34
|
-
assert !result[0]
|
34
|
+
assert !result[0]
|
35
35
|
assert result[1].any? {|message| !message.index("Maestro clouds config directory does not exist").nil? }
|
36
36
|
end
|
37
37
|
|
38
38
|
should "be invalid due to clouds not a directory" do
|
39
39
|
ENV[Maestro::MAESTRO_DIR_ENV_VAR] = File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'invalid-clouds-not-a-directory')
|
40
40
|
result = Maestro.validate_configs
|
41
|
-
assert !result[0]
|
41
|
+
assert !result[0]
|
42
42
|
assert result[1].any? {|message| !message.index("Maestro clouds config directory is not a directory").nil? }
|
43
43
|
end
|
44
44
|
|
45
45
|
should "be invalid due to missing cookbooks directory" do
|
46
46
|
ENV[Maestro::MAESTRO_DIR_ENV_VAR] = File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'invalid-missing-cookbooks')
|
47
47
|
result = Maestro.validate_configs
|
48
|
-
assert !result[0]
|
48
|
+
assert !result[0]
|
49
49
|
assert result[1].any? {|message| !message.index("Chef cookbooks directory does not exist").nil? }
|
50
50
|
end
|
51
51
|
|
52
52
|
should "be invalid due to cookbooks not a directory" do
|
53
53
|
ENV[Maestro::MAESTRO_DIR_ENV_VAR] = File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'invalid-cookbooks-not-a-directory')
|
54
54
|
result = Maestro.validate_configs
|
55
|
-
assert !result[0]
|
55
|
+
assert !result[0]
|
56
56
|
assert result[1].any? {|message| !message.index("Chef cookbooks directory is not a directory").nil? }
|
57
57
|
end
|
58
58
|
|
59
59
|
should "be invalid due to missing roles directory" do
|
60
60
|
ENV[Maestro::MAESTRO_DIR_ENV_VAR] = File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'invalid-missing-roles')
|
61
61
|
result = Maestro.validate_configs
|
62
|
-
assert !result[0]
|
62
|
+
assert !result[0]
|
63
63
|
assert result[1].any? {|message| !message.index("Chef roles directory does not exist").nil? }
|
64
64
|
end
|
65
65
|
|
66
66
|
should "be invalid due to roles not a directory" do
|
67
67
|
ENV[Maestro::MAESTRO_DIR_ENV_VAR] = File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'invalid-roles-not-a-directory')
|
68
68
|
result = Maestro.validate_configs
|
69
|
-
assert !result[0]
|
69
|
+
assert !result[0]
|
70
70
|
assert result[1].any? {|message| !message.index("Chef roles directory is not a directory").nil? }
|
71
71
|
end
|
72
72
|
|
data/the-maestro.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{the-maestro}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.4.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Brian Ploetz"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-10-05}
|
13
13
|
s.description = %q{Maestro is a cloud provisioning, configuration, and management utility for your Ruby and Ruby On Rails applications.}
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"LICENSE",
|
@@ -34,6 +34,7 @@ Gem::Specification.new do |s|
|
|
34
34
|
"lib/maestro/operating_system/debian.rb",
|
35
35
|
"lib/maestro/operating_system/fedora.rb",
|
36
36
|
"lib/maestro/operating_system/ubuntu.rb",
|
37
|
+
"lib/maestro/railtie.rb",
|
37
38
|
"lib/maestro/role.rb",
|
38
39
|
"lib/maestro/tasks.rb",
|
39
40
|
"lib/maestro/validator.rb",
|
@@ -80,7 +81,7 @@ Gem::Specification.new do |s|
|
|
80
81
|
s.homepage = %q{http://github.com/bploetz/maestro}
|
81
82
|
s.rdoc_options = ["--charset=UTF-8"]
|
82
83
|
s.require_paths = ["lib"]
|
83
|
-
s.rubygems_version = %q{1.3.
|
84
|
+
s.rubygems_version = %q{1.3.7}
|
84
85
|
s.summary = %q{Maestro: Conduct your clouds.}
|
85
86
|
s.test_files = [
|
86
87
|
"test/integration/base_aws.rb",
|
@@ -116,7 +117,7 @@ Gem::Specification.new do |s|
|
|
116
117
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
117
118
|
s.specification_version = 3
|
118
119
|
|
119
|
-
if Gem::Version.new(Gem::
|
120
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
120
121
|
s.add_development_dependency(%q<thoughtbot-shoulda>, ["= 2.10.2"])
|
121
122
|
s.add_runtime_dependency(%q<net-ssh>, ["= 2.0.15"])
|
122
123
|
s.add_runtime_dependency(%q<net-scp>, ["= 1.0.2"])
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: the-maestro
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 4
|
8
|
+
- 0
|
9
|
+
version: 0.4.0
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Brian Ploetz
|
@@ -9,99 +14,144 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date: 2010-
|
17
|
+
date: 2010-10-05 00:00:00 -04:00
|
13
18
|
default_executable:
|
14
19
|
dependencies:
|
15
20
|
- !ruby/object:Gem::Dependency
|
16
21
|
name: thoughtbot-shoulda
|
17
|
-
|
18
|
-
|
19
|
-
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
20
25
|
requirements:
|
21
26
|
- - "="
|
22
27
|
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 2
|
30
|
+
- 10
|
31
|
+
- 2
|
23
32
|
version: 2.10.2
|
24
|
-
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
25
35
|
- !ruby/object:Gem::Dependency
|
26
36
|
name: net-ssh
|
27
|
-
|
28
|
-
|
29
|
-
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
30
40
|
requirements:
|
31
41
|
- - "="
|
32
42
|
- !ruby/object:Gem::Version
|
43
|
+
segments:
|
44
|
+
- 2
|
45
|
+
- 0
|
46
|
+
- 15
|
33
47
|
version: 2.0.15
|
34
|
-
|
48
|
+
type: :runtime
|
49
|
+
version_requirements: *id002
|
35
50
|
- !ruby/object:Gem::Dependency
|
36
51
|
name: net-scp
|
37
|
-
|
38
|
-
|
39
|
-
|
52
|
+
prerelease: false
|
53
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
40
55
|
requirements:
|
41
56
|
- - "="
|
42
57
|
- !ruby/object:Gem::Version
|
58
|
+
segments:
|
59
|
+
- 1
|
60
|
+
- 0
|
61
|
+
- 2
|
43
62
|
version: 1.0.2
|
44
|
-
|
63
|
+
type: :runtime
|
64
|
+
version_requirements: *id003
|
45
65
|
- !ruby/object:Gem::Dependency
|
46
66
|
name: net-ssh-multi
|
47
|
-
|
48
|
-
|
49
|
-
|
67
|
+
prerelease: false
|
68
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
50
70
|
requirements:
|
51
71
|
- - "="
|
52
72
|
- !ruby/object:Gem::Version
|
73
|
+
segments:
|
74
|
+
- 1
|
75
|
+
- 0
|
76
|
+
- 1
|
53
77
|
version: 1.0.1
|
54
|
-
|
78
|
+
type: :runtime
|
79
|
+
version_requirements: *id004
|
55
80
|
- !ruby/object:Gem::Dependency
|
56
81
|
name: net-ssh-gateway
|
57
|
-
|
58
|
-
|
59
|
-
|
82
|
+
prerelease: false
|
83
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
60
85
|
requirements:
|
61
86
|
- - "="
|
62
87
|
- !ruby/object:Gem::Version
|
88
|
+
segments:
|
89
|
+
- 1
|
90
|
+
- 0
|
91
|
+
- 1
|
63
92
|
version: 1.0.1
|
64
|
-
|
93
|
+
type: :runtime
|
94
|
+
version_requirements: *id005
|
65
95
|
- !ruby/object:Gem::Dependency
|
66
96
|
name: archive-tar-minitar
|
67
|
-
|
68
|
-
|
69
|
-
|
97
|
+
prerelease: false
|
98
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
99
|
+
none: false
|
70
100
|
requirements:
|
71
101
|
- - "="
|
72
102
|
- !ruby/object:Gem::Version
|
103
|
+
segments:
|
104
|
+
- 0
|
105
|
+
- 5
|
106
|
+
- 2
|
73
107
|
version: 0.5.2
|
74
|
-
|
108
|
+
type: :runtime
|
109
|
+
version_requirements: *id006
|
75
110
|
- !ruby/object:Gem::Dependency
|
76
111
|
name: amazon-ec2
|
77
|
-
|
78
|
-
|
79
|
-
|
112
|
+
prerelease: false
|
113
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
80
115
|
requirements:
|
81
116
|
- - "="
|
82
117
|
- !ruby/object:Gem::Version
|
118
|
+
segments:
|
119
|
+
- 0
|
120
|
+
- 9
|
121
|
+
- 11
|
83
122
|
version: 0.9.11
|
84
|
-
|
123
|
+
type: :runtime
|
124
|
+
version_requirements: *id007
|
85
125
|
- !ruby/object:Gem::Dependency
|
86
126
|
name: aws-s3
|
87
|
-
|
88
|
-
|
89
|
-
|
127
|
+
prerelease: false
|
128
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
90
130
|
requirements:
|
91
131
|
- - "="
|
92
132
|
- !ruby/object:Gem::Version
|
133
|
+
segments:
|
134
|
+
- 0
|
135
|
+
- 6
|
136
|
+
- 2
|
93
137
|
version: 0.6.2
|
94
|
-
|
138
|
+
type: :runtime
|
139
|
+
version_requirements: *id008
|
95
140
|
- !ruby/object:Gem::Dependency
|
96
141
|
name: log4r
|
97
|
-
|
98
|
-
|
99
|
-
|
142
|
+
prerelease: false
|
143
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
144
|
+
none: false
|
100
145
|
requirements:
|
101
146
|
- - "="
|
102
147
|
- !ruby/object:Gem::Version
|
148
|
+
segments:
|
149
|
+
- 1
|
150
|
+
- 1
|
151
|
+
- 7
|
103
152
|
version: 1.1.7
|
104
|
-
|
153
|
+
type: :runtime
|
154
|
+
version_requirements: *id009
|
105
155
|
description: Maestro is a cloud provisioning, configuration, and management utility for your Ruby and Ruby On Rails applications.
|
106
156
|
email:
|
107
157
|
executables: []
|
@@ -130,6 +180,7 @@ files:
|
|
130
180
|
- lib/maestro/operating_system/debian.rb
|
131
181
|
- lib/maestro/operating_system/fedora.rb
|
132
182
|
- lib/maestro/operating_system/ubuntu.rb
|
183
|
+
- lib/maestro/railtie.rb
|
133
184
|
- lib/maestro/role.rb
|
134
185
|
- lib/maestro/tasks.rb
|
135
186
|
- lib/maestro/validator.rb
|
@@ -182,21 +233,25 @@ rdoc_options:
|
|
182
233
|
require_paths:
|
183
234
|
- lib
|
184
235
|
required_ruby_version: !ruby/object:Gem::Requirement
|
236
|
+
none: false
|
185
237
|
requirements:
|
186
238
|
- - ">="
|
187
239
|
- !ruby/object:Gem::Version
|
240
|
+
segments:
|
241
|
+
- 0
|
188
242
|
version: "0"
|
189
|
-
version:
|
190
243
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
244
|
+
none: false
|
191
245
|
requirements:
|
192
246
|
- - ">="
|
193
247
|
- !ruby/object:Gem::Version
|
248
|
+
segments:
|
249
|
+
- 0
|
194
250
|
version: "0"
|
195
|
-
version:
|
196
251
|
requirements: []
|
197
252
|
|
198
253
|
rubyforge_project:
|
199
|
-
rubygems_version: 1.3.
|
254
|
+
rubygems_version: 1.3.7
|
200
255
|
signing_key:
|
201
256
|
specification_version: 3
|
202
257
|
summary: "Maestro: Conduct your clouds."
|