engineyard-recipes 0.0.1

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