breeze 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,14 +1,17 @@
1
1
  # breeze
2
2
 
3
3
  Breeze provides some [Thor](https://github.com/wycats/thor) tasks and example scripts for managing cloud computing resources
4
- and deployments on [Amazon's AWS cloud](http://aws.amazon.com/). It uses [fog](https://github.com/geemus/fog) for the hard
5
- work so it should be fairly easy to add support for other cloud computing providers that are supported by fog.
4
+ and deployments. Currently only [Amazon's AWS cloud](http://aws.amazon.com/) is supported, but breeze uses
5
+ [fog](https://github.com/geemus/fog) for the hard work so it should be fairly easy to add support for other cloud computing
6
+ providers that are supported by fog.
6
7
 
7
- Breeze implements zero downtime deployments by moving an elastic ip from one server to another. Db migrations have to be
8
- compatible with the previous version.
8
+ Breeze implements zero downtime deploys and rollbacks by moving an elastic ip from one server to another. Db migrations have to be
9
+ compatible with the previous version. http://pedro.herokuapp.com/past/2011/7/13/rails_migrations_with_no_downtime/
9
10
 
10
11
  ## install
11
12
 
13
+ Run the following commands to install breeze and initialize a new project with configuration file templates.
14
+
12
15
  gem install breeze
13
16
  cd your-project
14
17
  breeze init
@@ -21,10 +24,13 @@ for more information.
21
24
 
22
25
  ## create a server image
23
26
 
27
+ The command below installs a server and saves a private server image. When this is fully automated it can be
28
+ repeated with new software packages or a new OS version.
29
+
24
30
  thor server:image:create
25
31
 
26
32
  The default install.sh compiles ruby, passenger, nginx and image magick. It takes a long time
27
- (maybe half an hour on a small instance). It will prompt for the image name when completed.
33
+ (maybe half an hour on a small instance) and it will prompt for the image name when completed.
28
34
 
29
35
  ## use it
30
36
 
@@ -37,7 +43,7 @@ The default install.sh compiles ruby, passenger, nginx and image magick. It take
37
43
  thor staging:start # Start web server and db for staging
38
44
  thor staging:stop # Stop staging and destroy server and db
39
45
 
40
- Define your staging and production in the Thorfile and the same tasks become available for both name spaces.
46
+ Define your staging and production constants in the Thorfile and the same tasks become available for both name spaces.
41
47
  These tasks call app tasks with fixed parameters.
42
48
 
43
49
  ## plumbing commands
data/breeze.gemspec CHANGED
@@ -24,7 +24,7 @@ END_DESCRIPTION
24
24
  s.require_paths = ["lib"]
25
25
 
26
26
  s.add_dependency('thor')
27
- s.add_dependency('fog', '>= 0.7')
27
+ s.add_dependency('fog')
28
28
  s.add_development_dependency "cucumber"
29
29
  s.add_development_dependency "aruba"
30
30
  end
@@ -0,0 +1,23 @@
1
+ Feature: Getting started
2
+
3
+ As a new user I want to quickly get an idea of how breeze works.
4
+
5
+ Scenario: Start a new project
6
+ Given I have an empty working directory
7
+ When I run `breeze init`
8
+ Then a file named "Thorfile" should exist
9
+
10
+ Scenario: Start a new server
11
+ Given my Thorfile contains access credentials and configuration
12
+ When I run `thor server:create`
13
+ And I run `thor describe:servers`
14
+ Then the output should look like:
15
+ """
16
+ === SERVER INSTANCES ===========================================================================
17
+ Name Instance ID IP Address .* Image ID Type Zone State
18
+ YOUR-PRIVATE-AMI-OR-A-PUBLIC-ONE t1.micro us-east-1a running
19
+ """
20
+
21
+ Scenario: Terminate a server
22
+ Given I have started a server
23
+ Then I can terminate the server with `thor server:destroy [SERVER ID] --force`
@@ -0,0 +1,14 @@
1
+ Given /^I have an empty working directory$/ do
2
+ step "I run `rm -rf config Thorfile`"
3
+ end
4
+
5
+ Given /^my Thorfile contains access credentials and configuration$/ do
6
+ # the Thorfile should be okay already, just check it
7
+ check_file_content('Thorfile', "CONFIGURATION", true)
8
+ end
9
+
10
+ Then /^the output should look like:$/ do |lines|
11
+ lines.each_line do |line|
12
+ all_output.should match(/#{line.strip}/)
13
+ end
14
+ end
@@ -0,0 +1,8 @@
1
+ Given /^I have started a server$/ do
2
+ step "I run `thor server:create`"
3
+ @started_server_id = $1 if all_stdout =~ /server (i-[^.])\.\.\./
4
+ end
5
+
6
+ Then /^I can terminate the server with `thor server:destroy \[SERVER ID\] \-\-force`$/ do
7
+ step "I successfully run `thor server:destroy #{@started_server_id} --force`"
8
+ end
@@ -16,13 +16,17 @@ END_SCRIPT
16
16
  # and commands that make changes to the local system.
17
17
  system("rm -rf #{template_dir}/config/breeze/configs/*")
18
18
 
19
- # Use the current source insted of the installed gem.
19
+ # Use the current source with bundler insted of the installed gem.
20
20
  thorfile_path = File.join(template_dir, 'Thorfile')
21
21
  thorfile_content = File.read(thorfile_path)
22
- expected_require = "require 'breeze'"
23
- wanted_require = "require 'bundler'; Bundler.setup; require 'breeze'"
24
- raise "Cannot find #{expected_require} in #{thorfile_path}" unless thorfile_content.include?(expected_require)
25
- File.open(thorfile_path, 'w') { |f| f.puts(thorfile_content.sub(expected_require, wanted_require)) }
22
+ { # replace thorfile content:
23
+ "require 'breeze'" => "require 'bundler'; Bundler.setup; require 'breeze'",
24
+ "'THE-NAME-OF-YOUR-KEYPAIR'" => 'nil'
25
+ }.each do |expected, wanted|
26
+ raise "Cannot find #{expected} in #{thorfile_path}" unless thorfile_content.include?(expected)
27
+ thorfile_content.sub!(expected, wanted)
28
+ end
29
+ File.open(thorfile_path, 'w') { |f| f.puts(thorfile_content) }
26
30
 
27
31
  # Use Fog.mock!
28
32
  system("echo 'Fog.mock!' >> #{thorfile_path}")
@@ -30,4 +34,5 @@ system("echo 'Fog.mock!' >> #{thorfile_path}")
30
34
  # Clone the test app for each scenario.
31
35
  Before do
32
36
  system("cp -r #{template_dir} tmp/aruba")
37
+ @aruba_timeout_seconds = 5
33
38
  end
data/lib/breeze.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Breeze
2
2
 
3
- VERSION = "0.0.4"
3
+ VERSION = "0.0.5"
4
4
  autoload :Veur, 'breeze/veur'
5
5
 
6
6
  end
@@ -1,10 +1,10 @@
1
- require 'fog/compute/models/aws/server'
2
- require 'fog/compute/models/aws/image'
1
+ require 'fog/aws/models/compute/server'
2
+ require 'fog/aws/models/compute/image'
3
3
 
4
4
  module Fog
5
5
 
6
- module AWS
7
- class Compute::Server
6
+ module Compute
7
+ class AWS::Server
8
8
 
9
9
  def name
10
10
  breeze_data['name'] || tags['Name']
@@ -54,7 +54,7 @@ module Fog
54
54
  end
55
55
 
56
56
  end
57
- class Compute::Image
57
+ class AWS::Image
58
58
 
59
59
  def display_name
60
60
  name or location
@@ -0,0 +1,73 @@
1
+ require 'breeze/fog_extensions'
2
+ module Breeze
3
+
4
+ # The fog wrapper makes it possible for subsequent shell commands
5
+ # to share the same fog mock session. If Fog.mocking? is true, the
6
+ # mock data is read from and written to a yaml file.
7
+ module FogWrapper
8
+
9
+ def self.connection(type)
10
+ {:compute => Compute, :rds => RDS}[type].get_connection
11
+ end
12
+
13
+ def self.flush_mock_data!
14
+ Compute.new.flush_data!
15
+ # RDS.new.flush_data!
16
+ end
17
+
18
+ class AbstractConnectionWrapper
19
+
20
+ def self.get_connection
21
+ Fog.mocking? ? new : direct_fog_connection
22
+ end
23
+
24
+ def method_missing(*args)
25
+ load_data
26
+ return_value = fog.send(*args)
27
+ flush_data!
28
+ return_value
29
+ end
30
+
31
+ def flush_data!
32
+ File.open(data_file, 'w') { |f| YAML::dump(get_data, f) }
33
+ end
34
+
35
+ private
36
+
37
+ def fog
38
+ @fog ||= self.class.direct_fog_connection
39
+ end
40
+ def load_data
41
+ set_data(YAML::load_file(data_file)) if File.exists?(data_file)
42
+ end
43
+ def get_data
44
+ mock_class.instance_variable_get('@data')
45
+ end
46
+ def set_data(data)
47
+ mock_class.instance_variable_set('@data', data)
48
+ end
49
+ end
50
+
51
+ class Compute < AbstractConnectionWrapper
52
+ def self.direct_fog_connection
53
+ Fog::Compute.new(CONFIGURATION[:cloud_service])
54
+ end
55
+ private
56
+ def data_file ; 'fog_compute_data.yaml' ; end
57
+ def mock_class ; Fog::Compute::AWS::Mock ; end
58
+ end
59
+
60
+ # TODO: add RDS mocks to fog so that we can start testing it
61
+ class RDS < AbstractConnectionWrapper
62
+ def self.direct_fog_connection
63
+ credentials = CONFIGURATION[:cloud_service].reject{ |k,v| k == :provider }
64
+ credentials[:region] = CONFIGURATION[:db_region]
65
+ Fog::AWS::RDS.new(credentials)
66
+ end
67
+ private
68
+ def data_file ; 'fog_rds_data.yaml' ; end
69
+ def mock_class ; Fog::AWS::RDS::Mock ; end
70
+ end
71
+
72
+ end
73
+ end
@@ -33,17 +33,19 @@ module Breeze
33
33
  server = fog.servers.create(options)
34
34
  print "Launching server #{server.id}"
35
35
  wait_until('running!') { server.running? }
36
+ FogWrapper.flush_mock_data! if Fog.mocking?
36
37
  return server
37
38
  end
38
39
 
39
40
  # Can take a host name or an ip address. Resolves the host name
40
41
  # and returns the ip address if get_ip is passed in as true.
41
42
  def wait_until_host_is_available(host, get_ip=false)
42
- if Resolv.getaddresses(host).empty?
43
+ resolved_host = Resolv.getaddresses(host).first
44
+ if resolved_host.nil?
43
45
  print("Waiting for #{host} to resolve")
44
- wait_until('ready!') { Resolv.getaddresses(host).any? }
46
+ wait_until('ready!') { resolved_host = Resolv.getaddresses(host).first }
45
47
  end
46
- host = Resolv.getaddresses(host).first if get_ip
48
+ host = resolved_host if get_ip
47
49
  unless remote_is_available?(host)
48
50
  print("Waiting for #{host} to accept connections")
49
51
  wait_until('ready!') { remote_is_available?(host) }
data/lib/breeze/veur.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'breeze/fog_extensions'
1
+ require 'breeze/fog_wrapper'
2
2
 
3
3
  module Breeze
4
4
 
@@ -38,7 +38,14 @@ module Breeze
38
38
  # wait_until { my_task.completed? }
39
39
  def wait_until(message='completed!')
40
40
  3.times { dot_and_sleep(1) }
41
- dot_and_sleep(2) until yield
41
+ begin
42
+ dot_and_sleep(2) until yield
43
+ rescue Excon::Errors::SocketError => e
44
+ # print out the error so the user can interrupt if necessary
45
+ print "#{e.class}: #{e.message}! Retry:"
46
+ sleep(1)
47
+ retry
48
+ end
42
49
  puts message
43
50
  end
44
51
 
@@ -68,7 +75,7 @@ module Breeze
68
75
  end
69
76
 
70
77
  def fog
71
- @fog ||= Fog::Compute.new(CONFIGURATION[:cloud_service])
78
+ @fog ||= Breeze::FogWrapper.connection(:compute)
72
79
  end
73
80
 
74
81
  def dns
@@ -76,10 +83,7 @@ module Breeze
76
83
  end
77
84
 
78
85
  def rds
79
- return @rds if @rds
80
- credentials = CONFIGURATION[:cloud_service].reject{ |k,v| k == :provider }
81
- credentials[:region] = CONFIGURATION[:db_region]
82
- @rds = Fog::AWS::RDS.new(credentials)
86
+ @rds ||= Breeze::FogWrapper.connection(:rds)
83
87
  end
84
88
 
85
89
  end
metadata CHANGED
@@ -1,89 +1,76 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: breeze
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 0
8
- - 4
9
- version: 0.0.4
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.5
5
+ prerelease:
10
6
  platform: ruby
11
- authors:
7
+ authors:
12
8
  - Markus Bengts
13
9
  autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
-
17
- date: 2011-04-19 00:00:00 +02:00
18
- default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2012-01-13 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: thor
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70318976130880 !ruby/object:Gem::Requirement
24
17
  none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- segments:
29
- - 0
30
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
31
22
  type: :runtime
32
- version_requirements: *id001
33
- - !ruby/object:Gem::Dependency
34
- name: fog
35
23
  prerelease: false
36
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *70318976130880
25
+ - !ruby/object:Gem::Dependency
26
+ name: fog
27
+ requirement: &70318976130460 !ruby/object:Gem::Requirement
37
28
  none: false
38
- requirements:
39
- - - ">="
40
- - !ruby/object:Gem::Version
41
- segments:
42
- - 0
43
- - 7
44
- version: "0.7"
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
45
33
  type: :runtime
46
- version_requirements: *id002
47
- - !ruby/object:Gem::Dependency
48
- name: cucumber
49
34
  prerelease: false
50
- requirement: &id003 !ruby/object:Gem::Requirement
35
+ version_requirements: *70318976130460
36
+ - !ruby/object:Gem::Dependency
37
+ name: cucumber
38
+ requirement: &70318976146200 !ruby/object:Gem::Requirement
51
39
  none: false
52
- requirements:
53
- - - ">="
54
- - !ruby/object:Gem::Version
55
- segments:
56
- - 0
57
- version: "0"
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
58
44
  type: :development
59
- version_requirements: *id003
60
- - !ruby/object:Gem::Dependency
61
- name: aruba
62
45
  prerelease: false
63
- requirement: &id004 !ruby/object:Gem::Requirement
46
+ version_requirements: *70318976146200
47
+ - !ruby/object:Gem::Dependency
48
+ name: aruba
49
+ requirement: &70318976145400 !ruby/object:Gem::Requirement
64
50
  none: false
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- segments:
69
- - 0
70
- version: "0"
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
71
55
  type: :development
72
- version_requirements: *id004
73
- description: |
74
- Breeze makes it easy to automate server installation and configuration. It provides
56
+ prerelease: false
57
+ version_requirements: *70318976145400
58
+ description: ! 'Breeze makes it easy to automate server installation and configuration.
59
+ It provides
60
+
75
61
  example scripts and configuration files that you can modify and keep in your revision
76
- control system. Thor tasks are provided to create server images, launch server instances etc.
77
62
 
78
- email:
63
+ control system. Thor tasks are provided to create server images, launch server instances
64
+ etc.
65
+
66
+ '
67
+ email:
79
68
  - markus.bengts@gmail.com
80
- executables:
69
+ executables:
81
70
  - breeze
82
71
  extensions: []
83
-
84
72
  extra_rdoc_files: []
85
-
86
- files:
73
+ files:
87
74
  - .gitignore
88
75
  - Gemfile
89
76
  - LICENSE
@@ -92,10 +79,14 @@ files:
92
79
  - bin/breeze
93
80
  - breeze.gemspec
94
81
  - features/erb_conf.feature
82
+ - features/getting_started.feature
83
+ - features/step_definitions/application_steps.rb
84
+ - features/step_definitions/server_steps.rb
95
85
  - features/support/env.rb
96
86
  - lib/breeze.rb
97
87
  - lib/breeze/fog_extensions.rb
98
88
  - lib/breeze/fog_extensions/aws.rb
89
+ - lib/breeze/fog_wrapper.rb
99
90
  - lib/breeze/initializer.rb
100
91
  - lib/breeze/tasks.rb
101
92
  - lib/breeze/tasks/app.rb
@@ -125,38 +116,33 @@ files:
125
116
  - lib/templates/shared/scripts/deploy.sh
126
117
  - lib/templates/shared/scripts/install.sh
127
118
  - lib/templates/user_data.sh
128
- has_rdoc: true
129
119
  homepage: https://github.com/markus/breeze
130
120
  licenses: []
131
-
132
121
  post_install_message:
133
122
  rdoc_options: []
134
-
135
- require_paths:
123
+ require_paths:
136
124
  - lib
137
- required_ruby_version: !ruby/object:Gem::Requirement
125
+ required_ruby_version: !ruby/object:Gem::Requirement
138
126
  none: false
139
- requirements:
140
- - - ">="
141
- - !ruby/object:Gem::Version
142
- segments:
143
- - 0
144
- version: "0"
145
- required_rubygems_version: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ! '>='
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ required_rubygems_version: !ruby/object:Gem::Requirement
146
132
  none: false
147
- requirements:
148
- - - ">="
149
- - !ruby/object:Gem::Version
150
- segments:
151
- - 0
152
- version: "0"
133
+ requirements:
134
+ - - ! '>='
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
153
137
  requirements: []
154
-
155
138
  rubyforge_project: breeze
156
- rubygems_version: 1.3.7
139
+ rubygems_version: 1.8.11
157
140
  signing_key:
158
141
  specification_version: 3
159
142
  summary: Thor tasks to manage cloud computing resources and deployments
160
- test_files:
143
+ test_files:
161
144
  - features/erb_conf.feature
145
+ - features/getting_started.feature
146
+ - features/step_definitions/application_steps.rb
147
+ - features/step_definitions/server_steps.rb
162
148
  - features/support/env.rb