engineyard-recipes 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.
Files changed (34) hide show
  1. data/.gitignore +6 -0
  2. data/Gemfile +4 -0
  3. data/README.md +11 -0
  4. data/Rakefile +1 -0
  5. data/bin/ey-recipes +17 -0
  6. data/engineyard-recipes.gemspec +33 -0
  7. data/features/init-new-cookbook.feature +18 -0
  8. data/features/step_definitions/api_steps.rb +10 -0
  9. data/features/step_definitions/common_steps.rb +211 -0
  10. data/features/step_definitions/fixture_project_steps.rb +14 -0
  11. data/features/step_definitions/jenkins_steps.rb +21 -0
  12. data/features/support/common.rb +51 -0
  13. data/features/support/env.rb +18 -0
  14. data/features/support/matchers.rb +10 -0
  15. data/fixtures/bin/README.md +4 -0
  16. data/fixtures/bin/scp +6 -0
  17. data/fixtures/cookbooks/main/recipes/default.rb +1 -0
  18. data/fixtures/cookbooks/redis/recipes/default.rb +0 -0
  19. data/fixtures/jenkins_boot_sequence/jenkins_booting.html +1 -0
  20. data/fixtures/jenkins_boot_sequence/jenkins_ready.html +1 -0
  21. data/fixtures/jenkins_boot_sequence/pre_jenkins_booting.html +1 -0
  22. data/fixtures/projects/rails/Gemfile +3 -0
  23. data/fixtures/projects/rails/Rakefile +4 -0
  24. data/lib/engineyard-recipes/cli.rb +86 -0
  25. data/lib/engineyard-recipes/generators/init_generator/templates/cookbooks/main/attributes/recipe.rb +3 -0
  26. data/lib/engineyard-recipes/generators/init_generator/templates/cookbooks/main/definitions/ey_cloud_report.rb +6 -0
  27. data/lib/engineyard-recipes/generators/init_generator/templates/cookbooks/main/libraries/ruby_block.rb +40 -0
  28. data/lib/engineyard-recipes/generators/init_generator/templates/cookbooks/main/libraries/run_for_app.rb +12 -0
  29. data/lib/engineyard-recipes/generators/init_generator/templates/cookbooks/main/recipes/default.rb +0 -0
  30. data/lib/engineyard-recipes/generators/init_generator.rb +38 -0
  31. data/lib/engineyard-recipes/thor-ext/actions/directory.rb +33 -0
  32. data/lib/engineyard-recipes/version.rb +5 -0
  33. data/lib/engineyard-recipes.rb +7 -0
  34. metadata +149 -0
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .DS_Store
6
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in engineyard-recipes.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,11 @@
1
+ # Engine Yard Recipes
2
+
3
+ Tools to generate, upload, test and apply chef recipes for Engine Yard Cloud.
4
+
5
+ ## Usage
6
+
7
+ ```
8
+ $ cd /path/to/my/app
9
+ $ ey-recipes init
10
+ cookbooks/main/attributes/default.rb
11
+ cookbooks/main/recipes/default.rb
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/ey-recipes ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
4
+ require 'engineyard-recipes'
5
+ require 'engineyard-recipes/cli'
6
+
7
+ begin
8
+ Engineyard::Recipes::CLI.start
9
+ rescue EY::Error => e
10
+ EY.ui.print_exception(e)
11
+ exit(1)
12
+ rescue Interrupt => e
13
+ puts
14
+ EY.ui.print_exception(e)
15
+ EY.ui.say("Quitting...")
16
+ exit(1)
17
+ end
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "engineyard-recipes/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "engineyard-recipes"
7
+ s.version = Engineyard::Recipes::VERSION
8
+ s.authors = ["Dr Nic Williams"]
9
+ s.email = ["drnicwilliams@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Tools to generate, upload, test and apply chef recipes for Engine Yard Cloud.}
12
+ s.description = %q{Tools to generate, upload, test and apply chef recipes for Engine Yard Cloud.}
13
+
14
+ s.rubyforge_project = "engineyard-recipes"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency("thor", ["~> 0.14.6"])
22
+ s.add_dependency("engineyard", ["~> 1.4.6"])
23
+
24
+ s.add_development_dependency("rake", ["~> 0.9.2"])
25
+ s.add_development_dependency("cucumber", ["~> 1.1.2"])
26
+ s.add_development_dependency("rspec", ["~> 2.7.0"])
27
+ # s.add_development_dependency("json")
28
+ # s.add_development_dependency("awesome_print")
29
+ # s.add_development_dependency("realweb", '~>0.1.6')
30
+ # s.add_development_dependency("open4")
31
+ # s.add_development_dependency("sinatra")
32
+ # s.add_development_dependency("fakeweb", "~>1.3.0")
33
+ end
@@ -0,0 +1,18 @@
1
+ Feature: Generate a new custom cookbook for your EY Cloud environments
2
+
3
+ Scenario: Generate basic cookbook scaffold
4
+ Given I am in the "rails" project folder
5
+ When I run local executable "ey-recipes" with arguments "init"
6
+ And file "cookbooks/main/recipes/default.rb" is created
7
+ And file "cookbooks/main/libraries/ruby_block.rb" is created
8
+ And I should see exactly
9
+ """
10
+ create cookbooks
11
+ create cookbooks/main/attributes/recipe.rb
12
+ create cookbooks/main/definitions/ey_cloud_report.rb
13
+ create cookbooks/main/libraries/ruby_block.rb
14
+ create cookbooks/main/libraries/run_for_app.rb
15
+ create cookbooks/main/recipes/default.rb
16
+
17
+ Lovely.
18
+ """
@@ -0,0 +1,10 @@
1
+ Given /^I have setup my engineyard email\/password for API access$/ do
2
+ ENV['EYRC'] = File.join(@home_path, ".eyrc")
3
+ token = { ENV['CLOUD_URL'] => {
4
+ "api_token" => "f81a1706ddaeb148cfb6235ddecfc1cf"} }
5
+ File.open(ENV['EYRC'], "w"){|f| YAML.dump(token, f) }
6
+ end
7
+
8
+ When /^I have "two accounts, two apps, two environments, ambiguous"$/ do
9
+ api_scenario "two accounts, two apps, two environments, ambiguous"
10
+ end
@@ -0,0 +1,211 @@
1
+ Given /^this project is active project folder/ do
2
+ @active_project_folder = File.expand_path(File.dirname(__FILE__) + "/../..")
3
+ end
4
+
5
+ Given /^env variable \$([\w_]+) set to( project path|) "(.*)"/ do |env_var, path, value|
6
+ in_project_folder {
7
+ value = File.expand_path(value)
8
+ } unless path.empty?
9
+ ENV[env_var] = value
10
+ end
11
+
12
+ Given /"(.*)" folder is deleted/ do |folder|
13
+ in_project_folder { FileUtils.rm_rf folder }
14
+ end
15
+
16
+ When /^I invoke "(.*)" generator with arguments "(.*)"$/ do |generator, arguments|
17
+ @stdout = StringIO.new
18
+ in_project_folder do
19
+ if Object.const_defined?("APP_ROOT")
20
+ APP_ROOT.replace(FileUtils.pwd)
21
+ else
22
+ APP_ROOT = FileUtils.pwd
23
+ end
24
+ run_generator(generator, arguments.split(' '), SOURCES, :stdout => @stdout)
25
+ end
26
+ File.open(File.join(@tmp_root, "generator.out"), "w") do |f|
27
+ @stdout.rewind
28
+ f << @stdout.read
29
+ end
30
+ end
31
+
32
+ When /^I run executable "(.*)" with arguments "(.*)"/ do |executable, arguments|
33
+ @stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
34
+ in_project_folder do
35
+ system "#{executable.inspect} #{arguments} > #{@stdout.inspect} 2> #{@stdout.inspect}"
36
+ end
37
+ end
38
+
39
+ When /^I run project executable "(.*)" with arguments "(.*)"/ do |executable, arguments|
40
+ @stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
41
+ in_project_folder do
42
+ system "ruby -rubygems #{executable.inspect} #{arguments} > #{@stdout.inspect} 2> #{@stdout.inspect}"
43
+ end
44
+ end
45
+
46
+ When /^I run local executable "(.*)" with arguments "(.*)"/ do |executable, arguments|
47
+ if executable == "ey-recipes"
48
+ require 'engineyard-recipes'
49
+ require 'engineyard-recipes/cli'
50
+ in_project_folder do
51
+ stdout, stderr = capture_stdios do
52
+ Engineyard::Recipes::CLI.start(arguments.split(/ /))
53
+ end
54
+ @stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
55
+ File.open(@stdout, "w") {|f| f << stdout; f << stderr}
56
+ end
57
+ else
58
+ @stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
59
+ executable = File.expand_path(File.join(File.dirname(__FILE__), "/../../bin", executable))
60
+ in_project_folder do
61
+ system "ruby -rubygems #{executable.inspect} #{arguments} > #{@stdout.inspect} 2> #{@stdout.inspect}"
62
+ end
63
+ end
64
+ end
65
+
66
+ When /^I invoke task "rake (.*)"/ do |task|
67
+ @stdout = File.expand_path(File.join(@tmp_root, "tests.out"))
68
+ in_project_folder do
69
+ system "bundle exec rake #{task} --trace > #{@stdout.inspect} 2> #{@stdout.inspect}"
70
+ end
71
+ end
72
+
73
+ Then /^folder "(.*)" (is|is not) created/ do |folder, is|
74
+ in_project_folder do
75
+ File.exists?(folder).should(is == 'is' ? be_true : be_false)
76
+ end
77
+ end
78
+
79
+ Then /^file "(.*)" (is|is not) created/ do |file, is|
80
+ in_project_folder do
81
+ File.exists?(file).should(is == 'is' ? be_true : be_false)
82
+ end
83
+ end
84
+
85
+ Then /^file with name matching "(.*)" is created/ do |pattern|
86
+ in_project_folder do
87
+ Dir[pattern].should_not be_empty
88
+ end
89
+ end
90
+
91
+ Then /^file "(.*)" contents (does|does not) match \/(.*)\// do |file, does, regex|
92
+ in_project_folder do
93
+ actual_output = File.read(file)
94
+ (does == 'does') ?
95
+ actual_output.should(match(/#{regex}/)) :
96
+ actual_output.should_not(match(/#{regex}/))
97
+ end
98
+ end
99
+
100
+ Then /^file "([^"]*)" contains "([^"]*)"$/ do |file, text|
101
+ in_project_folder do
102
+ actual_output = File.read(file)
103
+ actual_output.should contain(text)
104
+ end
105
+ end
106
+
107
+
108
+ Then /gem file "(.*)" and generated file "(.*)" should be the same/ do |gem_file, project_file|
109
+ File.exists?(gem_file).should be_true
110
+ File.exists?(project_file).should be_true
111
+ gem_file_contents = File.read(File.dirname(__FILE__) + "/../../#{gem_file}")
112
+ project_file_contents = File.read(File.join(@active_project_folder, project_file))
113
+ project_file_contents.should == gem_file_contents
114
+ end
115
+
116
+ Then /^(does|does not) invoke generator "(.*)"$/ do |does_invoke, generator|
117
+ actual_output = get_command_output
118
+ does_invoke == "does" ?
119
+ actual_output.should(match(/dependency\s+#{generator}/)) :
120
+ actual_output.should_not(match(/dependency\s+#{generator}/))
121
+ end
122
+
123
+ Then /help options "(.*)" and "(.*)" are displayed/ do |opt1, opt2|
124
+ actual_output = get_command_output
125
+ actual_output.should match(/#{opt1}/)
126
+ actual_output.should match(/#{opt2}/)
127
+ end
128
+
129
+ Then /^I should see "([^\"]*)"$/ do |text|
130
+ actual_output = get_command_output
131
+ actual_output.should contain(text)
132
+ end
133
+
134
+ Then /^I should not see "([^\"]*)"$/ do |text|
135
+ actual_output =
136
+ actual_output.should_not contain(text)
137
+ end
138
+
139
+ Then /^I should see$/ do |text|
140
+ actual_output = get_command_output
141
+ actual_output.should contain(text)
142
+ end
143
+
144
+ Then /^I should not see$/ do |text|
145
+ actual_output = get_command_output
146
+ actual_output.should_not contain(text)
147
+ end
148
+
149
+ Then /^I should see exactly$/ do |text|
150
+ actual_output = get_command_output
151
+ actual_output.should == text
152
+ end
153
+
154
+ Then /^I should see all (\d+) tests pass/ do |expected_test_count|
155
+ expected = %r{^#{expected_test_count} tests, \d+ assertions, 0 failures, 0 errors}
156
+ actual_output = get_command_output
157
+ actual_output.should match(expected)
158
+ end
159
+
160
+ Then /^I should see all (\d+) examples pass/ do |expected_test_count|
161
+ expected = %r{^#{expected_test_count} examples?, 0 failures}
162
+ actual_output = get_command_output
163
+ actual_output.should match(expected)
164
+ end
165
+
166
+ Then /^yaml file "(.*)" contains (\{.*\})/ do |file, yaml|
167
+ in_project_folder do
168
+ yaml = eval yaml
169
+ YAML.load(File.read(file)).should == yaml
170
+ end
171
+ end
172
+
173
+ Then /^Rakefile can display tasks successfully/ do
174
+ @stdout = File.expand_path(File.join(@tmp_root, "rakefile.out"))
175
+ in_project_folder do
176
+ system "rake -T > #{@stdout.inspect} 2> #{@stdout.inspect}"
177
+ end
178
+ actual_output = get_command_output
179
+ actual_output.should match(/^rake\s+\w+\s+#\s.*/)
180
+ end
181
+
182
+ Then /^task "rake (.*)" is executed successfully/ do |task|
183
+ @stdout.should_not be_nil
184
+ actual_output = get_command_output
185
+ actual_output.should_not match(/^Don't know how to build task '#{task}'/)
186
+ actual_output.should_not match(/Error/i)
187
+ end
188
+
189
+ Then /^gem spec key "(.*)" contains \/(.*)\// do |key, regex|
190
+ in_project_folder do
191
+ gem_file = Dir["pkg/*.gem"].first
192
+ gem_spec = Gem::Specification.from_yaml(`gem spec #{gem_file}`)
193
+ spec_value = gem_spec.send(key.to_sym)
194
+ spec_value.to_s.should match(/#{regex}/)
195
+ end
196
+ end
197
+
198
+ Then /^the file "([^\"]*)" is a valid gemspec$/ do |filename|
199
+ spec = eval(File.read(filename))
200
+ spec.validate
201
+ end
202
+
203
+ When /^I create a new node with the following options on "http:\/\/(.+?):(\d+)":$/ do |host, port, table|
204
+ options = table.raw.inject({}) do |options, (key, value)|
205
+ options[(key.to_sym rescue key) || key] = value
206
+ options
207
+ end
208
+
209
+ Recipes::Api.setup_base_url(:host => host, :port => port.to_i)
210
+ Recipes::Api.add_node(options)
211
+ end
@@ -0,0 +1,14 @@
1
+ Given /^I am in the "([^\"]*)" project folder$/ do |project|
2
+ project_folder = File.expand_path(File.join(@fixtures_path, "projects", project))
3
+ in_tmp_folder do
4
+ FileUtils.cp_r(project_folder, project)
5
+ setup_active_project_folder(project)
6
+ end
7
+ end
8
+
9
+ Given /^I already have cookbooks installed$/ do
10
+ cookbooks_folder = File.expand_path(File.join(@fixtures_path, "cookbooks"))
11
+ in_project_folder do
12
+ FileUtils.cp_r(cookbooks_folder, ".")
13
+ end
14
+ end
@@ -0,0 +1,21 @@
1
+ Given /^I want to fake out the boot sequence of Recipes$/ do
2
+ base_path = File.join(File.dirname(__FILE__) + "/../../fixtures/Recipes_boot_sequence/")
3
+ FakeWeb.register_uri(:get, "http://app-master-hostname.compute-1.amazonaws.com/", [
4
+ {:body => File.read(base_path + "pre_Recipes_booting.html")},
5
+ {:body => File.read(base_path + "Recipes_booting.html")},
6
+ {:body => File.read(base_path + "Recipes_ready.html")}
7
+ ])
8
+ end
9
+
10
+ Given /^I have public key "([^"]*)" on host "([^"]*)"$/ do |public_key_value, host|
11
+ mock_target = File.expand_path("../../../tmp/scp_mock", __FILE__)
12
+ File.open(mock_target, "w") { |file| file << public_key_value }
13
+ end
14
+
15
+ Given /^I set "([^"]*)" as the default Recipes server$/ do |host|
16
+ require "Recipes"
17
+ require "Recipes/config"
18
+ Recipes::Api.setup_base_url(:host => host, :port => 80)
19
+ Recipes::Api.send(:cache_base_uri)
20
+ end
21
+
@@ -0,0 +1,51 @@
1
+ module CommonHelpers
2
+ def get_command_output
3
+ strip_color_codes(File.read(@stdout)).chomp
4
+ end
5
+
6
+ def strip_color_codes(text)
7
+ text.gsub(/\e\[\d+m/, '')
8
+ end
9
+
10
+ def in_tmp_folder(&block)
11
+ FileUtils.chdir(@tmp_root, &block)
12
+ end
13
+
14
+ def in_project_folder(&block)
15
+ project_folder = @active_project_folder || @tmp_root
16
+ FileUtils.chdir(project_folder, &block)
17
+ end
18
+
19
+ def in_home_folder(&block)
20
+ FileUtils.chdir(@home_path, &block)
21
+ end
22
+
23
+ def force_local_lib_override(project_name = @project_name)
24
+ rakefile = File.read(File.join(project_name, 'Rakefile'))
25
+ File.open(File.join(project_name, 'Rakefile'), "w+") do |f|
26
+ f << "$:.unshift('#{@lib_path}')\n"
27
+ f << rakefile
28
+ end
29
+ end
30
+
31
+ def setup_active_project_folder project_name
32
+ @active_project_folder = File.join(@tmp_root, project_name)
33
+ @project_name = project_name
34
+ end
35
+
36
+ # capture both [stdout, stderr] as well as stdin
37
+ def capture_stdios(input = nil, &block)
38
+ require 'stringio'
39
+ org_stdin, $stdin = $stdin, StringIO.new(input) if input
40
+ org_stdout, $stdout = $stdout, StringIO.new
41
+ org_stderr, $stderr = $stdout, StringIO.new
42
+ yield
43
+ return [$stdout.string, $stderr.string]
44
+ ensure
45
+ $stderr = org_stderr
46
+ $stdout = org_stdout
47
+ $stdin = org_stdin
48
+ end
49
+ end
50
+
51
+ World(CommonHelpers)
@@ -0,0 +1,18 @@
1
+ $:.unshift(File.expand_path(File.dirname(__FILE__) + '/../../lib'))
2
+ require 'bundler/setup'
3
+ require 'engineyard-recipes'
4
+
5
+ path = ENV['PATH']
6
+
7
+ Before do
8
+ @tmp_root = File.dirname(__FILE__) + "/../../tmp"
9
+ @active_project_folder = @tmp_root
10
+ @home_path = File.expand_path(File.join(@tmp_root, "home"))
11
+ @lib_path = File.expand_path(File.dirname(__FILE__) + "/../../lib")
12
+ @fixtures_path = File.expand_path(File.dirname(__FILE__) + "/../../fixtures")
13
+ FileUtils.rm_rf @tmp_root
14
+ FileUtils.mkdir_p @home_path
15
+ ENV['HOME'] = @home_path
16
+ fixture_bin_path = File.expand_path('../../../fixtures/bin', __FILE__)
17
+ ENV['PATH'] = fixture_bin_path + ":" + path
18
+ end
@@ -0,0 +1,10 @@
1
+
2
+ module Matchers
3
+ RSpec::Matchers.define :contain do |expected_text|
4
+ match do |text|
5
+ text.index expected_text
6
+ end
7
+ end
8
+ end
9
+
10
+ World(Matchers)
@@ -0,0 +1,4 @@
1
+ # Stubbed bin scripts
2
+
3
+ If a bin/executable script is used by the CLI, a fake version is provided here during the test suites, as necessary.
4
+
data/fixtures/bin/scp ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "fileutils"
4
+
5
+ mock_target = File.expand_path("../../../tmp/scp_mock", __FILE__)
6
+ FileUtils.cp_r(mock_target, ARGV[-1])
@@ -0,0 +1 @@
1
+ require_recipe 'redis'
File without changes
@@ -0,0 +1 @@
1
+ Please wait while Recipes is getting ready to work
@@ -0,0 +1 @@
1
+ Recipes is up!
@@ -0,0 +1 @@
1
+ This is some page before the instance is launched.
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.rb"
2
+
3
+ gem "rake"
@@ -0,0 +1,4 @@
1
+ desc "Default task runs tests"
2
+ task :default do
3
+ puts "Tests ran successfully!"
4
+ end
@@ -0,0 +1,86 @@
1
+ require 'thor'
2
+ require 'engineyard-recipes/thor-ext/actions/directory'
3
+
4
+ module Engineyard
5
+ module Recipes
6
+ class CLI < Thor
7
+
8
+ desc "init", "Creates cookbooks scaffolding for your recipes"
9
+ def init
10
+ require 'engineyard-recipes/generators/init_generator'
11
+ Engineyard::Recipes::Generators::InitGenerator.start
12
+ end
13
+
14
+ desc "version", "show version information"
15
+ def version
16
+ require 'engineyard-recipes/version'
17
+ shell.say Engineyard::Recipes::VERSION
18
+ end
19
+
20
+ map "-v" => :version, "--version" => :version, "-h" => :help, "--help" => :help
21
+
22
+ private
23
+ def say(msg, color = nil)
24
+ color ? shell.say(msg, color) : shell.say(msg)
25
+ end
26
+
27
+ def display(text)
28
+ shell.say text
29
+ exit
30
+ end
31
+
32
+ def error(text)
33
+ shell.say "ERROR: #{text}", :red
34
+ exit
35
+ end
36
+
37
+ # Returns the [host, port] for the target Recipes CI server
38
+ def host_port(options)
39
+ require "recipes"
40
+ require "recipes/config"
41
+ if base_uri = ::Recipes::Config.config['base_uri']
42
+ uri = URI.parse(::Recipes::Config.config['base_uri'])
43
+ host = uri.host
44
+ port = uri.port
45
+ end
46
+ host = options["host"] if options["host"]
47
+ port = options["port"] || port || '80'
48
+ [host, port]
49
+ end
50
+
51
+ def no_environments_discovered
52
+ say "No environments with name recipes, recipes_server, recipes_production, recipes_server_production.", :red
53
+ say "Either:"
54
+ say " * Create an Engine Yard Cloud environment called recipes, recipes_server, recipes_production, recipes_server_production"
55
+ say " * Use --environment/--account flags to select Engine Yard Cloud environment"
56
+ end
57
+
58
+ def too_many_environments_discovered(environments)
59
+ say "Multiple environments possible, please be more specific:", :red
60
+ say ""
61
+ environments.each do |env_name, account_name, environment|
62
+ say " ey-recipes install_server --environment "; say "'#{env_name}' ", :yellow;
63
+ say "--account "; say "'#{account_name}'", :yellow
64
+ end
65
+ end
66
+
67
+ def watch_page_while(host, port, path)
68
+ waiting = true
69
+ while waiting
70
+ begin
71
+ Net::HTTP.start(host, port) do |http|
72
+ req = http.get(path)
73
+ waiting = yield req
74
+ end
75
+ sleep 1; print '.'; $stdout.flush
76
+ rescue SocketError => e
77
+ sleep 1; print 'x'; $stdout.flush
78
+ rescue Exception => e
79
+ puts e.message
80
+ sleep 1; print '.'; $stdout.flush
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,3 @@
1
+ recipes('main')
2
+ owner_name(@attribute[:users].first[:username])
3
+ owner_pass(@attribute[:users].first[:password])
@@ -0,0 +1,6 @@
1
+ define :ey_cloud_report do
2
+ execute "reporting for #{params[:name]}" do
3
+ command "ey-enzyme --report '#{params[:message]}'"
4
+ epic_fail true
5
+ end
6
+ end
@@ -0,0 +1,40 @@
1
+
2
+ class Chef
3
+ class Resource
4
+ class RubyBlock < Chef::Resource
5
+ def initialize(name, collection=nil, node=nil)
6
+ super(name, collection, node)
7
+ @resource_name = :ruby_block
8
+ @action = :create
9
+ @allowed_actions.push(:create)
10
+ end
11
+
12
+ def block(&block)
13
+ if block
14
+ @block = block
15
+ else
16
+ @block
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+
24
+ class Chef
25
+ class Provider
26
+ class RubyBlock < Chef::Provider
27
+ def load_current_resource
28
+ Chef::Log.debug(@new_resource.inspect)
29
+ true
30
+ end
31
+
32
+ def action_create
33
+ @new_resource.block.call
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ Chef::Platform.platforms[:default].merge! :ruby_block => Chef::Provider::RubyBlock
40
+
@@ -0,0 +1,12 @@
1
+ class Chef
2
+ class Recipe
3
+ def run_for_app(*apps, &block)
4
+ apps.map! {|a| a.to_s }
5
+ node[:applications].map{|k,v| [k,v] }.sort_by {|a,b| a }.each do |name, app_data|
6
+ if apps.include?(name)
7
+ block.call(name, app_data)
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,38 @@
1
+ require 'thor/group'
2
+
3
+ module Engineyard::Recipes
4
+ module Generators
5
+ class InitGenerator < Thor::Group
6
+ include Thor::Actions
7
+
8
+ def self.source_root
9
+ File.join(File.dirname(__FILE__), "init_generator", "templates")
10
+ end
11
+
12
+ def install_cookbooks
13
+ file = "cookbooks/main/recipes/default.rb"
14
+ unless File.exists?(File.join(destination_root, "cookbooks/main/recipes/default.rb"))
15
+ directory "cookbooks"
16
+ end
17
+ end
18
+
19
+ # def attributes
20
+ # template "attributes.rb.tt", "cookbooks/recipes_slave/attributes/default.rb"
21
+ # end
22
+ #
23
+ # def recipe
24
+ # copy_file "recipes.rb", "cookbooks/recipes_slave/recipes/default.rb"
25
+ # end
26
+ #
27
+ def readme
28
+ say ""
29
+ say "Lovely.", :green
30
+ end
31
+
32
+ private
33
+ def say(msg, color = nil)
34
+ color ? shell.say(msg, color) : shell.say(msg)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,33 @@
1
+ # Extension: Sorts the Dir[lookup] to ensure deterministic ordering of actions
2
+ # to allow test assertions
3
+
4
+ class Thor
5
+ module Actions
6
+ class Directory < EmptyDirectory #:nodoc:
7
+ protected
8
+
9
+ def execute!
10
+ lookup = config[:recursive] ? File.join(source, '**') : source
11
+ lookup = File.join(lookup, '{*,.[a-z]*}')
12
+
13
+ Dir[lookup].sort.each do |file_source|
14
+ next if File.directory?(file_source)
15
+ file_destination = File.join(given_destination, file_source.gsub(source, '.'))
16
+ file_destination.gsub!('/./', '/')
17
+
18
+ case file_source
19
+ when /\.empty_directory$/
20
+ dirname = File.dirname(file_destination).gsub(/\/\.$/, '')
21
+ next if dirname == given_destination
22
+ base.empty_directory(dirname, config)
23
+ when /\.tt$/
24
+ destination = base.template(file_source, file_destination[0..-4], config, &@block)
25
+ else
26
+ destination = base.copy_file(file_source, file_destination, config, &@block)
27
+ end
28
+ end
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,5 @@
1
+ module Engineyard
2
+ module Recipes
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ require "engineyard-recipes/version"
2
+
3
+ module Engineyard
4
+ module Recipes
5
+ # Your code goes here...
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,149 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: engineyard-recipes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Dr Nic Williams
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-11-13 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: thor
16
+ requirement: &70345820762760 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.14.6
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70345820762760
25
+ - !ruby/object:Gem::Dependency
26
+ name: engineyard
27
+ requirement: &70345820762200 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 1.4.6
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70345820762200
36
+ - !ruby/object:Gem::Dependency
37
+ name: rake
38
+ requirement: &70345820761680 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 0.9.2
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70345820761680
47
+ - !ruby/object:Gem::Dependency
48
+ name: cucumber
49
+ requirement: &70345820761180 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.1.2
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70345820761180
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec
60
+ requirement: &70345820760660 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 2.7.0
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70345820760660
69
+ description: Tools to generate, upload, test and apply chef recipes for Engine Yard
70
+ Cloud.
71
+ email:
72
+ - drnicwilliams@gmail.com
73
+ executables:
74
+ - ey-recipes
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - .gitignore
79
+ - Gemfile
80
+ - README.md
81
+ - Rakefile
82
+ - bin/ey-recipes
83
+ - engineyard-recipes.gemspec
84
+ - features/init-new-cookbook.feature
85
+ - features/step_definitions/api_steps.rb
86
+ - features/step_definitions/common_steps.rb
87
+ - features/step_definitions/fixture_project_steps.rb
88
+ - features/step_definitions/jenkins_steps.rb
89
+ - features/support/common.rb
90
+ - features/support/env.rb
91
+ - features/support/matchers.rb
92
+ - fixtures/bin/README.md
93
+ - fixtures/bin/scp
94
+ - fixtures/cookbooks/main/recipes/default.rb
95
+ - fixtures/cookbooks/redis/recipes/default.rb
96
+ - fixtures/jenkins_boot_sequence/jenkins_booting.html
97
+ - fixtures/jenkins_boot_sequence/jenkins_ready.html
98
+ - fixtures/jenkins_boot_sequence/pre_jenkins_booting.html
99
+ - fixtures/projects/rails/Gemfile
100
+ - fixtures/projects/rails/Rakefile
101
+ - lib/engineyard-recipes.rb
102
+ - lib/engineyard-recipes/cli.rb
103
+ - lib/engineyard-recipes/generators/init_generator.rb
104
+ - lib/engineyard-recipes/generators/init_generator/templates/cookbooks/main/attributes/recipe.rb
105
+ - lib/engineyard-recipes/generators/init_generator/templates/cookbooks/main/definitions/ey_cloud_report.rb
106
+ - lib/engineyard-recipes/generators/init_generator/templates/cookbooks/main/libraries/ruby_block.rb
107
+ - lib/engineyard-recipes/generators/init_generator/templates/cookbooks/main/libraries/run_for_app.rb
108
+ - lib/engineyard-recipes/generators/init_generator/templates/cookbooks/main/recipes/default.rb
109
+ - lib/engineyard-recipes/thor-ext/actions/directory.rb
110
+ - lib/engineyard-recipes/version.rb
111
+ homepage: ''
112
+ licenses: []
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ none: false
119
+ requirements:
120
+ - - ! '>='
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ segments:
124
+ - 0
125
+ hash: -3089194490767720342
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ segments:
133
+ - 0
134
+ hash: -3089194490767720342
135
+ requirements: []
136
+ rubyforge_project: engineyard-recipes
137
+ rubygems_version: 1.8.6
138
+ signing_key:
139
+ specification_version: 3
140
+ summary: Tools to generate, upload, test and apply chef recipes for Engine Yard Cloud.
141
+ test_files:
142
+ - features/init-new-cookbook.feature
143
+ - features/step_definitions/api_steps.rb
144
+ - features/step_definitions/common_steps.rb
145
+ - features/step_definitions/fixture_project_steps.rb
146
+ - features/step_definitions/jenkins_steps.rb
147
+ - features/support/common.rb
148
+ - features/support/env.rb
149
+ - features/support/matchers.rb