engineyard-hudson 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. data/Gemfile.lock +42 -22
  2. data/Rakefile +6 -1
  3. data/engineyard-hudson.gemspec +10 -5
  4. data/features/install.feature +2 -6
  5. data/features/server.feature +40 -13
  6. data/features/step_definitions/api_steps.rb +10 -0
  7. data/features/step_definitions/common_steps.rb +16 -4
  8. data/features/step_definitions/hudson_steps.rb +8 -2
  9. data/features/support/common.rb +15 -1
  10. data/features/support/engineyard.rb +24 -0
  11. data/features/support/env.rb +2 -1
  12. data/fixtures/hudson_boot_sequence/hudson_booting.html +1 -0
  13. data/fixtures/hudson_boot_sequence/hudson_ready.html +1 -0
  14. data/fixtures/hudson_boot_sequence/pre_hudson_booting.html +1 -0
  15. data/lib/engineyard-hudson/appcloud_env.rb +49 -0
  16. data/lib/engineyard-hudson/cli.rb +73 -4
  17. data/lib/engineyard-hudson/cli/install_server.rb +25 -0
  18. data/lib/engineyard-hudson/cli/{server → install_server}/templates/attributes.rb.tt +0 -0
  19. data/lib/engineyard-hudson/cli/{server → install_server}/templates/cookbooks/hudson_master/recipes/default.rb +0 -0
  20. data/lib/engineyard-hudson/cli/{server → install_server}/templates/cookbooks/hudson_master/templates/default/init.sh.erb +0 -0
  21. data/lib/engineyard-hudson/cli/{server → install_server}/templates/cookbooks/hudson_master/templates/default/proxy.conf.erb +0 -0
  22. data/lib/engineyard-hudson/cli/{server → install_server}/templates/cookbooks/main/attributes/recipe.rb +0 -0
  23. data/lib/engineyard-hudson/cli/{server → install_server}/templates/cookbooks/main/definitions/ey_cloud_report.rb +0 -0
  24. data/lib/engineyard-hudson/cli/{server → install_server}/templates/cookbooks/main/libraries/ruby_block.rb +0 -0
  25. data/lib/engineyard-hudson/cli/{server → install_server}/templates/cookbooks/main/libraries/run_for_app.rb +0 -0
  26. data/lib/engineyard-hudson/cli/{server → install_server}/templates/cookbooks/main/recipes/default.rb +0 -0
  27. data/lib/engineyard-hudson/version.rb +1 -1
  28. data/spec/appcloud_env_spec.rb +75 -0
  29. data/spec/spec_helper.rb +4 -0
  30. metadata +112 -26
  31. data/lib/engineyard-hudson/cli/server.rb +0 -41
data/Gemfile.lock CHANGED
@@ -1,26 +1,28 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- engineyard-hudson (0.2.2)
5
- engineyard (~> 1.3.3)
6
- thor (~> 0.14.3)
4
+ engineyard-hudson (0.3.0)
5
+ engineyard (~> 1.3.4)
6
+ ruby-debug
7
+ thor (~> 0.14.6)
7
8
 
8
9
  GEM
9
10
  remote: http://rubygems.org/
10
11
  specs:
11
12
  awesome_print (0.2.1)
12
13
  builder (2.1.2)
13
- cucumber (0.9.3)
14
+ columnize (0.3.1)
15
+ cucumber (0.9.4)
14
16
  builder (~> 2.1.2)
15
17
  diff-lcs (~> 1.1.2)
16
18
  gherkin (~> 2.2.9)
17
19
  json (~> 1.4.6)
18
20
  term-ansicolor (~> 1.0.5)
19
21
  diff-lcs (1.1.2)
20
- engineyard (1.3.3)
22
+ engineyard (1.3.4)
21
23
  engineyard-serverside-adapter (= 1.3.5)
22
24
  escape (~> 0.0.4)
23
- highline (~> 1.5.2)
25
+ highline (~> 1.6.1)
24
26
  json_pure
25
27
  rest-client (~> 1.4)
26
28
  thor (~> 0.14.3)
@@ -28,38 +30,56 @@ GEM
28
30
  escape (~> 0.0.4)
29
31
  json_pure
30
32
  escape (0.0.4)
33
+ fakeweb (1.3.0)
31
34
  gherkin (2.2.9)
32
35
  json (~> 1.4.6)
33
36
  term-ansicolor (~> 1.0.5)
34
- highline (1.5.2)
37
+ highline (1.6.1)
35
38
  json (1.4.6)
36
39
  json_pure (1.4.6)
40
+ linecache (0.43)
37
41
  mime-types (1.16)
42
+ open4 (1.0.1)
43
+ rack (1.2.1)
38
44
  rake (0.8.7)
45
+ realweb (0.1.6)
46
+ rack (>= 1.1.0)
39
47
  rest-client (1.6.1)
40
48
  mime-types (>= 1.16)
41
- rspec (2.0.1)
42
- rspec-core (~> 2.0.1)
43
- rspec-expectations (~> 2.0.1)
44
- rspec-mocks (~> 2.0.1)
45
- rspec-core (2.0.1)
46
- rspec-expectations (2.0.1)
47
- diff-lcs (>= 1.1.2)
48
- rspec-mocks (2.0.1)
49
- rspec-core (~> 2.0.1)
50
- rspec-expectations (~> 2.0.1)
49
+ rspec (2.1.0)
50
+ rspec-core (~> 2.1.0)
51
+ rspec-expectations (~> 2.1.0)
52
+ rspec-mocks (~> 2.1.0)
53
+ rspec-core (2.1.0)
54
+ rspec-expectations (2.1.0)
55
+ diff-lcs (~> 1.1.2)
56
+ rspec-mocks (2.1.0)
57
+ ruby-debug (0.10.3)
58
+ columnize (>= 0.1)
59
+ ruby-debug-base (~> 0.10.3.0)
60
+ ruby-debug-base (0.10.3)
61
+ linecache (>= 0.3)
62
+ sinatra (1.1.0)
63
+ rack (~> 1.1)
64
+ tilt (~> 1.1)
51
65
  term-ansicolor (1.0.5)
52
- thor (0.14.3)
66
+ thor (0.14.6)
67
+ tilt (1.1)
53
68
 
54
69
  PLATFORMS
55
70
  ruby
56
71
 
57
72
  DEPENDENCIES
58
73
  awesome_print
59
- cucumber (~> 0.9.3)
60
- engineyard (~> 1.3.3)
74
+ cucumber (~> 0.9.4)
75
+ engineyard (~> 1.3.4)
61
76
  engineyard-hudson!
77
+ fakeweb (~> 1.3.0)
62
78
  json (~> 1.4.0)
79
+ open4
63
80
  rake (~> 0.8.7)
64
- rspec (~> 2.0.1)
65
- thor (~> 0.14.3)
81
+ realweb (~> 0.1.6)
82
+ rspec (~> 2.1.0)
83
+ ruby-debug
84
+ sinatra
85
+ thor (~> 0.14.6)
data/Rakefile CHANGED
@@ -1,6 +1,11 @@
1
1
  require 'bundler'
2
2
  Bundler::GemHelper.install_tasks
3
3
 
4
+ require 'rspec/core/rake_task'
5
+
6
+ desc "Run all examples"
7
+ RSpec::Core::RakeTask.new
8
+
4
9
  namespace :cucumber do
5
10
  require 'cucumber/rake/task'
6
11
  Cucumber::Rake::Task.new(:wip, 'Run features that are being worked on') do |t|
@@ -16,4 +21,4 @@ desc 'Alias for cucumber:ok'
16
21
  task :cucumber => 'cucumber:ok'
17
22
 
18
23
  desc "Start test server; Run cucumber:ok; Kill Test Server;"
19
- task :default => ["cucumber"]
24
+ task :default => ["spec", "cucumber"]
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "engineyard-hudson"
5
- s.version = '0.2.2'
5
+ s.version = '0.3.0'
6
6
  s.platform = Gem::Platform::RUBY
7
7
  s.authors = ["Dr Nic Williams"]
8
8
  s.email = ["drnicwilliams@gmail.com"]
@@ -17,12 +17,17 @@ Gem::Specification.new do |s|
17
17
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
18
  s.require_paths = ["lib"]
19
19
 
20
- s.add_dependency("thor", ["~> 0.14.3"])
21
- s.add_dependency("engineyard", ["~> 1.3.3"])
20
+ s.add_dependency("thor", ["~> 0.14.6"])
21
+ s.add_dependency("engineyard", ["~> 1.3.4"])
22
22
 
23
23
  s.add_development_dependency("rake", ["~> 0.8.7"])
24
- s.add_development_dependency("cucumber", ["~> 0.9.3"])
25
- s.add_development_dependency("rspec", ["~> 2.0.1"])
24
+ s.add_development_dependency("cucumber", ["~> 0.9.4"])
25
+ s.add_development_dependency("rspec", ["~> 2.1.0"])
26
26
  s.add_development_dependency("json", ["~>1.4.0"])
27
27
  s.add_development_dependency("awesome_print")
28
+ s.add_development_dependency("realweb", '~>0.1.6')
29
+ s.add_development_dependency("open4")
30
+ s.add_development_dependency("sinatra")
31
+ s.add_development_dependency("fakeweb", "~>1.3.0")
32
+ s.add_dependency("ruby-debug")
28
33
  end
@@ -2,9 +2,7 @@ Feature: Managing a rails project as a Hudson CI job on AppCloud
2
2
  I want to build/test my project in the same environment I run in Engine Yard AppCloud
3
3
 
4
4
  Scenario: Setup first project as a slave for Hudson
5
- Given I have an environment "hudson" on account "drnic" on AppCloud
6
- And I have an environment "my_app_ci" on account "drnic" on AppCloud
7
- And I am in the "rails" project folder
5
+ Given I am in the "rails" project folder
8
6
  When I run local executable "ey-hudson" with arguments "install ."
9
7
  Then file "cookbooks/hudson_slave/attributes/default.rb" is created
10
8
  And file "cookbooks/hudson_slave/recipes/default.rb" is created
@@ -30,9 +28,7 @@ Feature: Managing a rails project as a Hudson CI job on AppCloud
30
28
  """
31
29
 
32
30
  Scenario: Setup project with existing cookbooks as a slave for Hudson
33
- Given I have an environment "hudson" on account "drnic" on AppCloud
34
- And I have an environment "my_app_ci" on account "drnic" on AppCloud
35
- And I am in the "rails" project folder
31
+ Given I am in the "rails" project folder
36
32
  And I already have cookbooks installed
37
33
  When I run local executable "ey-hudson" with arguments "install ."
38
34
  Then file "cookbooks/hudson_slave/attributes/default.rb" is created
@@ -1,9 +1,13 @@
1
1
  Feature: Managing ey hudson server
2
- I want to setup and manage a Hudson CI server hosted on Engine Yard AppCloud
2
+ I want to install a Hudson CI server hosted on Engine Yard AppCloud
3
3
 
4
- Scenario: Setup new Hudson CI server on AppCloud
5
- Given I have an environment "hudson" on account "drnic" on AppCloud
6
- When I run local executable "ey-hudson" with arguments "server ."
4
+ Background:
5
+ Given I have setup my engineyard email/password for API access
6
+ And I have "two accounts, two apps, two environments, ambiguous"
7
+ And I want to fake out the boot sequence of Hudson
8
+
9
+ Scenario: Install new Hudson CI server on AppCloud
10
+ When I run local executable "ey-hudson" with arguments "install_server . --account account_2 --environment giblets"
7
11
  Then file "cookbooks/main/recipes/default.rb" is created
8
12
  And file "cookbooks/hudson_master/recipes/default.rb" is created
9
13
  And file "cookbooks/hudson_master/attributes/default.rb" contains ":plugins => %w[git github rake ruby greenballs envfile]"
@@ -20,20 +24,43 @@ Feature: Managing ey hudson server
20
24
  create cookbooks/main/recipes/default.rb
21
25
  create cookbooks/hudson_master/attributes/default.rb
22
26
 
23
- Finally:
24
- * edit cookbooks/hudson_master/attributes/default.rb as necessary.
25
- * run: ey recipes upload # use --environment(-e) & --account(-c)
26
- * run: ey recipes apply # to select environment
27
- * Boot your environment if not already booted.
28
- When the recipe completes, your solo instance will host a Hudson CI!
27
+ Uploading to 'giblets' environment on 'account_2' account...
28
+ Environment is rebuilding...
29
+ ..
30
+ Hudson is starting...
31
+
32
+ Done! Hudson CI hosted at http://app-master-hostname.compute-1.amazonaws.com
29
33
  """
30
34
 
31
- Scenario: Setup Hudson CI server with additional Hudson plugins
32
- Given I have an environment "hudson" on account "drnic" on AppCloud
33
- When I run local executable "ey-hudson" with arguments "server . -p ' chucknorris , googleanalytics '"
35
+ @wip
36
+ Scenario: Install Hudson CI server with additional Hudson plugins
37
+ When I run local executable "ey-hudson" with arguments "install_server . -p ' chucknorris , googleanalytics ' -c account_2 -e giblets"
34
38
  Then file "cookbooks/main/recipes/default.rb" is created
35
39
  And file "cookbooks/hudson_master/recipes/default.rb" is created
36
40
  And file "cookbooks/hudson_master/attributes/default.rb" contains ":plugins => %w[git github rake ruby greenballs envfile chucknorris googleanalytics]"
41
+
42
+ Scenario: Display example explicit calls if multiple accounts/options
43
+ When I run local executable "ey-hudson" with arguments "install_server . -e giblets"
44
+ Then file "cookbooks/main/recipes/default.rb" is not created
45
+ And I should see exactly
46
+ """
47
+ Multiple environments possible, please be more specific:
48
+
49
+ ey-hudson install_server --environment 'giblets' --account 'main'
50
+ ey-hudson install_server --environment 'giblets' --account 'account_2'
51
+ """
52
+
53
+ Scenario: Ask for environment/account details if no obvious hudson environment on AppCloud
54
+ When I run local executable "ey-hudson" with arguments "install_server ."
55
+ Then file "cookbooks/main/recipes/default.rb" is not created
56
+ And I should see exactly
57
+ """
58
+ No environments with name hudson, hudson_server, hudson_production, hudson_server_production.
59
+ Either:
60
+ * Create an AppCloud environment called hudson, hudson_server, hudson_production, hudson_server_production
61
+ * Use --environment/--account flags to select AppCloud environment
62
+ """
63
+
37
64
 
38
65
 
39
66
 
@@ -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
@@ -44,10 +44,22 @@ When /^I run project executable "(.*)" with arguments "(.*)"/ do |executable, ar
44
44
  end
45
45
 
46
46
  When /^I run local executable "(.*)" with arguments "(.*)"/ do |executable, arguments|
47
- @stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
48
- executable = File.expand_path(File.join(File.dirname(__FILE__), "/../../bin", executable))
49
- in_project_folder do
50
- system "ruby -rubygems #{executable.inspect} #{arguments} > #{@stdout.inspect} 2> #{@stdout.inspect}"
47
+ if executable == "ey-hudson"
48
+ require 'engineyard-hudson'
49
+ require 'engineyard-hudson/cli'
50
+ in_project_folder do
51
+ stdout, stderr = capture_stdios do
52
+ Engineyard::Hudson::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
51
63
  end
52
64
  end
53
65
 
@@ -1,3 +1,9 @@
1
- Given /^I have an environment "([^"]*)" on account "([^"]*)" on AppCloud$/ do |env, account|
2
-
1
+ Given /^I want to fake out the boot sequence of Hudson$/ do
2
+ base_path = File.join(File.dirname(__FILE__) + "/../../fixtures/hudson_boot_sequence/")
3
+ FakeWeb.register_uri(:get, "http://app-master-hostname.compute-1.amazonaws.com/", [
4
+ {:body => File.read(base_path + "pre_hudson_booting.html")},
5
+ {:body => File.read(base_path + "hudson_booting.html")},
6
+ {:body => File.read(base_path + "hudson_ready.html")}
7
+ ])
3
8
  end
9
+
@@ -32,6 +32,20 @@ module CommonHelpers
32
32
  @active_project_folder = File.join(@tmp_root, project_name)
33
33
  @project_name = project_name
34
34
  end
35
- end
36
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
+
37
51
  World(CommonHelpers)
@@ -0,0 +1,24 @@
1
+ engineyard_loaded_path = $:.select { |path| path =~ %r|gems/engineyard-\d+| }.first
2
+ EY_ROOT = engineyard_loaded_path.gsub(%r|/\w+$|,'')
3
+
4
+ # helper to be stubbed out from engineyard spec_helper.rb
5
+ def shared_examples_for(title)
6
+ end
7
+
8
+ support = Dir[File.join(EY_ROOT,'/spec/support/*.rb')]
9
+ support.each{|helper| require helper }
10
+ World(Spec::Helpers)
11
+
12
+ require "fakeweb"
13
+
14
+ Before do
15
+ ENV["NO_SSH"] = "true"
16
+ ENV['CLOUD_URL'] = EY.fake_awsm
17
+ FakeWeb.allow_net_connect = true
18
+ end
19
+
20
+ After do
21
+ ENV.delete('CLOUD_URL')
22
+ ENV.delete('EYRC')
23
+ ENV.delete('NO_SSH')
24
+ end
@@ -1,9 +1,10 @@
1
1
  $:.unshift(File.expand_path(File.dirname(__FILE__) + '/../../lib'))
2
- require 'engineyard-hudson'
3
2
  require 'bundler/setup'
3
+ require 'engineyard-hudson'
4
4
 
5
5
  Before do
6
6
  @tmp_root = File.dirname(__FILE__) + "/../../tmp"
7
+ @active_project_folder = @tmp_root
7
8
  @home_path = File.expand_path(File.join(@tmp_root, "home"))
8
9
  @lib_path = File.expand_path(File.dirname(__FILE__) + "/../../lib")
9
10
  @fixtures_path = File.expand_path(File.dirname(__FILE__) + "/../../fixtures")
@@ -0,0 +1 @@
1
+ Please wait while Hudson is getting ready to work
@@ -0,0 +1 @@
1
+ Hudson is up!
@@ -0,0 +1 @@
1
+ This is some page before the instance is launched.
@@ -0,0 +1,49 @@
1
+ require "engineyard"
2
+ require "engineyard/thor"
3
+ require "engineyard/cli"
4
+ require "engineyard/cli/ui"
5
+ require "engineyard/error"
6
+ module Engineyard
7
+ module Hudson
8
+ class AppcloudEnv
9
+ include EY::UtilityMethods
10
+
11
+ # Returns [environment, account] based on current .eyrc credentials and/or CLI options
12
+ # Returns [nil, nil] if no unique environment can be selected
13
+ def find_environments(options = {})
14
+ Thor::Base.shell = EY::CLI::UI
15
+ EY.ui = EY::CLI::UI.new
16
+ query_environments = options[:environment] ? [options[:environment]] : default_query_environments
17
+ query_environments.inject([]) do |envs, env_name|
18
+ begin
19
+ if environment = fetch_environment(env_name, options[:account])
20
+ clean_host_name(environment)
21
+ envs << [env_name, environment.account.name, environment]
22
+ end
23
+ rescue EY::NoEnvironmentError
24
+ rescue EY::MultipleMatchesError => e
25
+ # e.message looks something like:
26
+ # Multiple environments possible, please be more specific:
27
+ #
28
+ # hudson # ey <command> --environment='hudson' --account='drnic-demo'
29
+ # hudson # ey <command> --environment='hudson' --account='rails-hudson'
30
+ e.message.scan(/--environment='([^']+)' --account='([^']+)'/) do
31
+ envs << [$1, $2, nil]
32
+ end
33
+ end
34
+ envs
35
+ end
36
+ end
37
+
38
+ def default_query_environments
39
+ %w[hudson hudson_server hudson_production hudson_server_production]
40
+ end
41
+
42
+ # Currently the engineyard gem has badly formed URLs in its same data
43
+ # This method cleans app_master_hostname.compute-1.amazonaws.com -> app-master-hostname.compute-1.amazonaws.com
44
+ def clean_host_name(environment)
45
+ environment.instances.first.public_hostname.gsub!(/_/,'-') if environment.instances.first
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,5 +1,6 @@
1
1
  require 'thor'
2
2
  require 'engineyard-hudson/thor-ext/actions/directory'
3
+ require 'engineyard-hudson/appcloud_env'
3
4
 
4
5
  module Engineyard
5
6
  module Hudson
@@ -11,10 +12,74 @@ module Engineyard
11
12
  Engineyard::Hudson::Install.start(ARGV[1..-1])
12
13
  end
13
14
 
14
- desc "server PROJECT_PATH", "Setup a Hudson CI server on AppCloud."
15
- def server(project_path)
16
- require 'engineyard-hudson/cli/server'
17
- Engineyard::Hudson::Server.start(ARGV[1..-1])
15
+ desc "install_server [PROJECT_PATH]", "Install Hudson CI into an AppCloud environment."
16
+ method_option :verbose, :aliases => ["-V"], :desc => "Display more output"
17
+ method_option :environment, :aliases => ["-e"], :desc => "Environment in which to deploy this application", :type => :string
18
+ method_option :account, :aliases => ["-c"], :desc => "Name of the account you want to deploy in"
19
+ def install_server(project_path=nil)
20
+ environments = Engineyard::Hudson::AppcloudEnv.new.find_environments(options)
21
+ if environments.size == 0
22
+ say "No environments with name hudson, hudson_server, hudson_production, hudson_server_production.", :red
23
+ say "Either:"
24
+ say " * Create an AppCloud environment called hudson, hudson_server, hudson_production, hudson_server_production"
25
+ say " * Use --environment/--account flags to select AppCloud environment"
26
+ return
27
+ elsif environments.size > 1
28
+ say "Multiple environments possible, please be more specific:", :red
29
+ say ""
30
+ environments.each do |env_name, account_name, environment|
31
+ say " ey-hudson install_server --environment "; say "'#{env_name}' ", :yellow;
32
+ say "--account "; say "'#{account_name}'", :yellow
33
+ end
34
+ return
35
+ end
36
+
37
+ env_name, account_name, environment = environments.first
38
+ public_hostname, status = environment.instances.first.public_hostname, environment.instances.first.status if environment.instances.first
39
+
40
+ temp_project_path = File.expand_path(project_path || File.join(Dir.tmpdir, "temp_hudson_server"))
41
+ shell.say "Temp installation dir: #{temp_project_path}" if options[:verbose]
42
+ FileUtils.mkdir_p(temp_project_path)
43
+ FileUtils.chdir(FileUtils.mkdir_p(temp_project_path)) do
44
+ require 'engineyard-hudson/cli/install_server'
45
+ Engineyard::Hudson::InstallServer.start(ARGV.unshift(temp_project_path))
46
+
47
+ require 'engineyard/cli/recipes'
48
+ say ""
49
+ say "Uploading to "; say "'#{env_name}' ", :yellow; say "environment on "; say "'#{account_name}' ", :yellow; say "account..."
50
+ environment.upload_recipes
51
+
52
+ if status == "running"
53
+ environment.run_custom_recipes
54
+ say "Environment is rebuilding..."
55
+ waiting = true
56
+ while waiting
57
+ begin
58
+ Net::HTTP.start(public_hostname, 80) do |http|
59
+ waiting = (body = http.get("/").body) !~ /Please wait while Hudson is getting ready to work/
60
+ end
61
+ sleep 1; print '.'; $stdout.flush
62
+ rescue SocketError => e
63
+ sleep 1; print 'x'; $stdout.flush
64
+ rescue Exception
65
+ sleep 1; print '.'; $stdout.flush
66
+ end
67
+ end
68
+ say ""
69
+ say "Hudson is starting..."
70
+ Net::HTTP.start(public_hostname, 80) do |http|
71
+ while http.get("/").body =~ /Please wait while Hudson is getting ready to work/
72
+ sleep 1; print '.'; $stdout.flush
73
+ end
74
+ end
75
+ say ""
76
+ say "Done! Hudson CI hosted at "; say "http://#{public_hostname}", :green
77
+ else
78
+ say ""
79
+ say "Almost there..."
80
+ say "* Boot your environment via https://cloud.engineyard.com", :yellow
81
+ end
82
+ end
18
83
  end
19
84
 
20
85
  desc "version", "show version information"
@@ -26,6 +91,10 @@ module Engineyard
26
91
  map "-v" => :version, "--version" => :version, "-h" => :help, "--help" => :help
27
92
 
28
93
  private
94
+ def say(msg, color = nil)
95
+ color ? shell.say(msg, color) : shell.say(msg)
96
+ end
97
+
29
98
  def display(text)
30
99
  shell.say text
31
100
  exit
@@ -0,0 +1,25 @@
1
+ require 'thor/group'
2
+
3
+ module Engineyard
4
+ module Hudson
5
+ class InstallServer < Thor::Group
6
+ include Thor::Actions
7
+
8
+ class_option :plugins, :aliases => '-p', :desc => 'additional Hudson CI plugins (comma separated)'
9
+
10
+ def self.source_root
11
+ File.join(File.dirname(__FILE__), "install_server", "templates")
12
+ end
13
+
14
+ def cookbooks
15
+ directory "cookbooks"
16
+ end
17
+
18
+ def attributes
19
+ @plugins = %w[git github rake ruby greenballs envfile] + (options[:plugins] || '').strip.split(/\s*,\s*/)
20
+ template "attributes.rb.tt", "cookbooks/hudson_master/attributes/default.rb"
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -1,5 +1,5 @@
1
1
  module Engineyard
2
2
  module Hudson
3
- VERSION = '0.2.2'
3
+ VERSION = '0.3.0'
4
4
  end
5
5
  end
@@ -0,0 +1,75 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ require 'engineyard-hudson/appcloud_env'
4
+
5
+ describe Engineyard::Hudson::AppcloudEnv do
6
+ def appcloud_env
7
+ @appcloud_env ||= Engineyard::Hudson::AppcloudEnv.new
8
+ end
9
+
10
+ def find_environments(options = {})
11
+ appcloud_env.find_environments(options)
12
+ end
13
+
14
+ before do
15
+ @tmp_root = File.dirname(__FILE__) + "/../tmp"
16
+ @home_path = File.expand_path(File.join(@tmp_root, "home"))
17
+ FileUtils.mkdir_p(@home_path)
18
+ ENV['EYRC'] = File.join(@home_path, ".eyrc")
19
+ appcloud_env.stub(:clean_host_name)
20
+ end
21
+ describe ".find_environments - no args" do
22
+ it "return [nil, nil] unless it has reason to return something else" do
23
+ appcloud_env.stub(:fetch_environment).and_raise(EY::NoEnvironmentError)
24
+ find_environments.should == []
25
+ end
26
+ it "returns [env_name, account_name] if finds one env 'hudson' in any account" do
27
+ appcloud_env.should_receive(:fetch_environment).with("hudson", nil).and_return(env = EY::Model::App.new(123, EY::Model::Account.new(789, 'mine')))
28
+ appcloud_env.should_receive(:fetch_environment).with("hudson_server", nil).and_raise(EY::NoEnvironmentError)
29
+ appcloud_env.should_receive(:fetch_environment).with("hudson_production", nil).and_raise(EY::NoEnvironmentError)
30
+ appcloud_env.should_receive(:fetch_environment).with("hudson_server_production", nil).and_raise(EY::NoEnvironmentError)
31
+ find_environments.should == [['hudson', 'mine', env]]
32
+ end
33
+ it "returns many result pairs" do
34
+ appcloud_env.should_receive(:fetch_environment).with("hudson", nil).and_return(env = EY::Model::App.new(123, EY::Model::Account.new(789, 'mine')))
35
+ appcloud_env.should_receive(:fetch_environment).with("hudson_server", nil).and_raise(EY::NoEnvironmentError)
36
+ appcloud_env.should_receive(:fetch_environment).with("hudson_server_production", nil).and_raise(EY::NoEnvironmentError)
37
+ appcloud_env.should_receive(:fetch_environment).with("hudson_production", nil) {
38
+ raise EY::MultipleMatchesError, <<-ERROR.gsub(/^\s+/, '')
39
+ hudson_production # ey <command> --environment='hudson_production' --account='mine'
40
+ hudson_production # ey <command> --environment='hudson_production' --account='yours'
41
+ ERROR
42
+ }
43
+ find_environments.should == [['hudson', 'mine', env], ['hudson_production', 'mine', nil], ['hudson_production', 'yours', nil]]
44
+ end
45
+ end
46
+
47
+ describe ".find_environments - specific account" do
48
+ it "return [nil, nil] unless it has reason to return something else" do
49
+ appcloud_env.stub(:fetch_environment).and_raise(EY::NoEnvironmentError)
50
+ find_environments(:account => "mine").should == []
51
+ end
52
+ it "returns [env_name, account_name] if finds one env 'hudson' in specific account" do
53
+ appcloud_env.should_receive(:fetch_environment).with("hudson", "mine").and_return(env = EY::Model::App.new(123, EY::Model::Account.new(789, 'mine')))
54
+ appcloud_env.should_receive(:fetch_environment).with("hudson_server", "mine").and_raise(EY::NoEnvironmentError)
55
+ appcloud_env.should_receive(:fetch_environment).with("hudson_production", "mine").and_raise(EY::NoEnvironmentError)
56
+ appcloud_env.should_receive(:fetch_environment).with("hudson_server_production", "mine").and_raise(EY::NoEnvironmentError)
57
+ find_environments(:account => "mine").should == [['hudson', 'mine', env]]
58
+ end
59
+ end
60
+
61
+ describe ".find_environments - specific environment" do
62
+ it "return [nil, nil] unless it has reason to return something else" do
63
+ appcloud_env.stub(:fetch_environment).and_raise(EY::NoEnvironmentError)
64
+ find_environments(:environment => "hudson").should == []
65
+ end
66
+ it "returns [env_name, account_name] if finds one env 'hudson' in any account" do
67
+ appcloud_env.should_receive(:fetch_environment).with("hudson", nil).and_return(env = EY::Model::App.new(123, EY::Model::Account.new(789, 'mine')))
68
+ find_environments(:environment => "hudson").should == [['hudson', 'mine', env]]
69
+ end
70
+ it "returns [env_name, account_name] if finds one env 'hudson' in specific account" do
71
+ appcloud_env.should_receive(:fetch_environment).with("hudson", "mine").and_return(env = EY::Model::App.new(123, EY::Model::Account.new(789, 'mine')))
72
+ find_environments(:environment => "hudson", :account => "mine").should == [['hudson', 'mine', env]]
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,4 @@
1
+ $:.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
2
+ require 'bundler/setup'
3
+ require 'engineyard-hudson'
4
+ require 'rspec'
metadata CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 2
9
- - 2
10
- version: 0.2.2
8
+ - 3
9
+ - 0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Dr Nic Williams
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-03 00:00:00 -07:00
18
+ date: 2010-11-24 00:00:00 -08:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -26,12 +26,12 @@ dependencies:
26
26
  requirements:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
- hash: 33
29
+ hash: 43
30
30
  segments:
31
31
  - 0
32
32
  - 14
33
- - 3
34
- version: 0.14.3
33
+ - 6
34
+ version: 0.14.6
35
35
  type: :runtime
36
36
  version_requirements: *id001
37
37
  - !ruby/object:Gem::Dependency
@@ -42,12 +42,12 @@ dependencies:
42
42
  requirements:
43
43
  - - ~>
44
44
  - !ruby/object:Gem::Version
45
- hash: 29
45
+ hash: 19
46
46
  segments:
47
47
  - 1
48
48
  - 3
49
- - 3
50
- version: 1.3.3
49
+ - 4
50
+ version: 1.3.4
51
51
  type: :runtime
52
52
  version_requirements: *id002
53
53
  - !ruby/object:Gem::Dependency
@@ -74,12 +74,12 @@ dependencies:
74
74
  requirements:
75
75
  - - ~>
76
76
  - !ruby/object:Gem::Version
77
- hash: 61
77
+ hash: 51
78
78
  segments:
79
79
  - 0
80
80
  - 9
81
- - 3
82
- version: 0.9.3
81
+ - 4
82
+ version: 0.9.4
83
83
  type: :development
84
84
  version_requirements: *id004
85
85
  - !ruby/object:Gem::Dependency
@@ -90,12 +90,12 @@ dependencies:
90
90
  requirements:
91
91
  - - ~>
92
92
  - !ruby/object:Gem::Version
93
- hash: 13
93
+ hash: 11
94
94
  segments:
95
95
  - 2
96
- - 0
97
96
  - 1
98
- version: 2.0.1
97
+ - 0
98
+ version: 2.1.0
99
99
  type: :development
100
100
  version_requirements: *id005
101
101
  - !ruby/object:Gem::Dependency
@@ -128,6 +128,80 @@ dependencies:
128
128
  version: "0"
129
129
  type: :development
130
130
  version_requirements: *id007
131
+ - !ruby/object:Gem::Dependency
132
+ name: realweb
133
+ prerelease: false
134
+ requirement: &id008 !ruby/object:Gem::Requirement
135
+ none: false
136
+ requirements:
137
+ - - ~>
138
+ - !ruby/object:Gem::Version
139
+ hash: 23
140
+ segments:
141
+ - 0
142
+ - 1
143
+ - 6
144
+ version: 0.1.6
145
+ type: :development
146
+ version_requirements: *id008
147
+ - !ruby/object:Gem::Dependency
148
+ name: open4
149
+ prerelease: false
150
+ requirement: &id009 !ruby/object:Gem::Requirement
151
+ none: false
152
+ requirements:
153
+ - - ">="
154
+ - !ruby/object:Gem::Version
155
+ hash: 3
156
+ segments:
157
+ - 0
158
+ version: "0"
159
+ type: :development
160
+ version_requirements: *id009
161
+ - !ruby/object:Gem::Dependency
162
+ name: sinatra
163
+ prerelease: false
164
+ requirement: &id010 !ruby/object:Gem::Requirement
165
+ none: false
166
+ requirements:
167
+ - - ">="
168
+ - !ruby/object:Gem::Version
169
+ hash: 3
170
+ segments:
171
+ - 0
172
+ version: "0"
173
+ type: :development
174
+ version_requirements: *id010
175
+ - !ruby/object:Gem::Dependency
176
+ name: fakeweb
177
+ prerelease: false
178
+ requirement: &id011 !ruby/object:Gem::Requirement
179
+ none: false
180
+ requirements:
181
+ - - ~>
182
+ - !ruby/object:Gem::Version
183
+ hash: 27
184
+ segments:
185
+ - 1
186
+ - 3
187
+ - 0
188
+ version: 1.3.0
189
+ type: :development
190
+ version_requirements: *id011
191
+ - !ruby/object:Gem::Dependency
192
+ name: ruby-debug
193
+ prerelease: false
194
+ requirement: &id012 !ruby/object:Gem::Requirement
195
+ none: false
196
+ requirements:
197
+ - - ">="
198
+ - !ruby/object:Gem::Version
199
+ hash: 3
200
+ segments:
201
+ - 0
202
+ version: "0"
203
+ type: :runtime
204
+ version_requirements: *id012
131
205
  description: Run your continuous integration (CI) tests against your Engine Yard AppCloud environments - the exact same configuration you are using in production!
132
206
  email:
133
207
  - drnicwilliams@gmail.com
@@ -148,18 +222,24 @@ files:
148
222
  - engineyard-hudson.gemspec
149
223
  - features/install.feature
150
224
  - features/server.feature
225
+ - features/step_definitions/api_steps.rb
151
226
  - features/step_definitions/common_steps.rb
152
227
  - features/step_definitions/fixture_project_steps.rb
153
228
  - features/step_definitions/hudson_steps.rb
154
229
  - features/support/common.rb
230
+ - features/support/engineyard.rb
155
231
  - features/support/env.rb
156
232
  - features/support/matchers.rb
157
233
  - fixtures/cookbooks/main/recipes/default.rb
158
234
  - fixtures/cookbooks/redis/recipes/default.rb
235
+ - fixtures/hudson_boot_sequence/hudson_booting.html
236
+ - fixtures/hudson_boot_sequence/hudson_ready.html
237
+ - fixtures/hudson_boot_sequence/pre_hudson_booting.html
159
238
  - fixtures/projects/rails/Gemfile
160
239
  - fixtures/projects/rails/Gemfile.lock
161
240
  - fixtures/projects/rails/Rakefile
162
241
  - lib/engineyard-hudson.rb
242
+ - lib/engineyard-hudson/appcloud_env.rb
163
243
  - lib/engineyard-hudson/cli.rb
164
244
  - lib/engineyard-hudson/cli/install.rb
165
245
  - lib/engineyard-hudson/cli/install/templates/attributes.rb.tt
@@ -168,18 +248,20 @@ files:
168
248
  - lib/engineyard-hudson/cli/install/templates/cookbooks/main/libraries/ruby_block.rb
169
249
  - lib/engineyard-hudson/cli/install/templates/cookbooks/main/libraries/run_for_app.rb
170
250
  - lib/engineyard-hudson/cli/install/templates/recipes.rb
171
- - lib/engineyard-hudson/cli/server.rb
172
- - lib/engineyard-hudson/cli/server/templates/attributes.rb.tt
173
- - lib/engineyard-hudson/cli/server/templates/cookbooks/hudson_master/recipes/default.rb
174
- - lib/engineyard-hudson/cli/server/templates/cookbooks/hudson_master/templates/default/init.sh.erb
175
- - lib/engineyard-hudson/cli/server/templates/cookbooks/hudson_master/templates/default/proxy.conf.erb
176
- - lib/engineyard-hudson/cli/server/templates/cookbooks/main/attributes/recipe.rb
177
- - lib/engineyard-hudson/cli/server/templates/cookbooks/main/definitions/ey_cloud_report.rb
178
- - lib/engineyard-hudson/cli/server/templates/cookbooks/main/libraries/ruby_block.rb
179
- - lib/engineyard-hudson/cli/server/templates/cookbooks/main/libraries/run_for_app.rb
180
- - lib/engineyard-hudson/cli/server/templates/cookbooks/main/recipes/default.rb
251
+ - lib/engineyard-hudson/cli/install_server.rb
252
+ - lib/engineyard-hudson/cli/install_server/templates/attributes.rb.tt
253
+ - lib/engineyard-hudson/cli/install_server/templates/cookbooks/hudson_master/recipes/default.rb
254
+ - lib/engineyard-hudson/cli/install_server/templates/cookbooks/hudson_master/templates/default/init.sh.erb
255
+ - lib/engineyard-hudson/cli/install_server/templates/cookbooks/hudson_master/templates/default/proxy.conf.erb
256
+ - lib/engineyard-hudson/cli/install_server/templates/cookbooks/main/attributes/recipe.rb
257
+ - lib/engineyard-hudson/cli/install_server/templates/cookbooks/main/definitions/ey_cloud_report.rb
258
+ - lib/engineyard-hudson/cli/install_server/templates/cookbooks/main/libraries/ruby_block.rb
259
+ - lib/engineyard-hudson/cli/install_server/templates/cookbooks/main/libraries/run_for_app.rb
260
+ - lib/engineyard-hudson/cli/install_server/templates/cookbooks/main/recipes/default.rb
181
261
  - lib/engineyard-hudson/thor-ext/actions/directory.rb
182
262
  - lib/engineyard-hudson/version.rb
263
+ - spec/appcloud_env_spec.rb
264
+ - spec/spec_helper.rb
183
265
  has_rdoc: true
184
266
  homepage: http://github.com/engineyard/engineyard-hudson
185
267
  licenses: []
@@ -217,9 +299,13 @@ summary: Easier to do CI than not to. Use Hudson CI with Engine Yard AppCloud.
217
299
  test_files:
218
300
  - features/install.feature
219
301
  - features/server.feature
302
+ - features/step_definitions/api_steps.rb
220
303
  - features/step_definitions/common_steps.rb
221
304
  - features/step_definitions/fixture_project_steps.rb
222
305
  - features/step_definitions/hudson_steps.rb
223
306
  - features/support/common.rb
307
+ - features/support/engineyard.rb
224
308
  - features/support/env.rb
225
309
  - features/support/matchers.rb
310
+ - spec/appcloud_env_spec.rb
311
+ - spec/spec_helper.rb
@@ -1,41 +0,0 @@
1
- require 'thor/group'
2
-
3
- module Engineyard
4
- module Hudson
5
- class Server < Thor::Group
6
- include Thor::Actions
7
-
8
- argument :project_path
9
-
10
- class_option :plugins, :aliases => '-p', :desc => 'additional Hudson CI plugins (comma separated)'
11
-
12
- def self.source_root
13
- File.join(File.dirname(__FILE__), "server", "templates")
14
- end
15
-
16
- def cookbooks
17
- directory "cookbooks"
18
- end
19
-
20
- def attributes
21
- @plugins = %w[git github rake ruby greenballs envfile] + (options[:plugins] || '').strip.split(/\s*,\s*/)
22
- template "attributes.rb.tt", "cookbooks/hudson_master/attributes/default.rb"
23
- end
24
-
25
- def readme
26
- say ""
27
- say "Finally:"
28
- say "* edit "; say "cookbooks/hudson_master/attributes/default.rb ", :yellow; say "as necessary."
29
- say "* run: "; say "ey recipes upload ", :green; say "# use --environment(-e) & --account(-c)"
30
- say "* run: "; say "ey recipes apply ", :green; say "# to select environment"
31
- say "* "; say "Boot your environment ", :yellow; say "if not already booted."
32
- say "When the recipe completes, your solo instance will host a Hudson CI!"
33
- end
34
-
35
- private
36
- def say(msg, color = nil)
37
- color ? shell.say(msg, color) : shell.say(msg)
38
- end
39
- end
40
- end
41
- end