eb_deployer 0.3.1 → 0.3.2

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8ff8dea9ecf894a081eabd4d8e790706b7f6f699
4
+ data.tar.gz: 32fb41ec3baa8c2a40d73cf7a7c69820a645bbc5
5
+ SHA512:
6
+ metadata.gz: 52589f810e24608c3978a47eadfe5d8a1cd759c025418ea0af29553accabcc0c9ed796b59026e01d6b3083bfd5205f15a5d0b484f5a97352caac7edac0f813de
7
+ data.tar.gz: ca45f1540987043188a8746ce510c59e6c9dd4f466506f9202b87d557875018a0506349d23b689a8d8d54994ca901bf6c3a853525f31a0a68961054f22b59c8e
data/lib/eb_deployer.rb CHANGED
@@ -34,7 +34,6 @@ module EbDeployer
34
34
  # @option opts [Symbol] :region AWS Region (e.g. "us-west-2", "us-east-1")
35
35
  #
36
36
  def self.query_resource_output(key, opts)
37
- # AWS.config(:logger => Logger.new($stdout))
38
37
  if region = opts[:region]
39
38
  AWS.config(:region => region)
40
39
  end
@@ -162,7 +161,6 @@ module EbDeployer
162
161
  # If specified as zero or not specified, all versions will be kept. If a
163
162
  # version_prefix is given, only removes version starting with the prefix.
164
163
  def self.deploy(opts)
165
- # AWS.config(:logger => Logger.new($stdout))
166
164
  if region = opts[:region]
167
165
  AWS.config(:region => region)
168
166
  end
@@ -278,6 +276,13 @@ module EbDeployer
278
276
  exit(0)
279
277
  end
280
278
 
279
+ opts.on("--debug", "Output AWS debug log") do |d|
280
+ require 'logger'
281
+ logger = Logger.new($stdout)
282
+ logger.level = Logger::DEBUG
283
+ AWS.config(:logger => logger)
284
+ end
285
+
281
286
  opts.on("-h", "--help", "help") do
282
287
  puts opts
283
288
  puts ""
@@ -11,7 +11,7 @@ module EbDeployer
11
11
  def create_version(version_label, package)
12
12
  create_application_if_not_exists
13
13
 
14
- source_bundle = if package =~ /\.yml$/
14
+ source_bundle = if File.extname(package) == '.yml'
15
15
  YAML.load(File.read(package))
16
16
  else
17
17
  package = Package.new(package, @bucket + ".packages", @s3_driver)
@@ -102,9 +102,8 @@ common:
102
102
  # keys:
103
103
  # template => CloudFormation template file with JSON format
104
104
  # inputs => A Hash, input values for the CloudFormation template
105
- # outputs => A Hash with key map to your CloudFormation
106
- # template outputs and value as elastic beanstalk settings namespace and option_name.
107
- # :capabilities => An array. You need set it to ['CAPABILITY_IAM'] if the
105
+ # outputs => A Hash with key map to your CloudFormation template outputs and value as elastic beanstalk settings namespace and option_name.
106
+ # capabilities => An array. You need set it to ['CAPABILITY_IAM'] if the
108
107
  # template include IAM Instance Profile.
109
108
  resources:
110
109
 
@@ -1,6 +1,7 @@
1
1
  module EbDeployer
2
2
  class Environment
3
3
  attr_reader :app, :name
4
+ attr_writer :event_poller
4
5
 
5
6
  def self.unique_ebenv_name(app_name, env_name)
6
7
  raise "Environment name #{env_name} is too long, it must be under 15 chars" if env_name.size > 15
@@ -15,7 +16,7 @@ module EbDeployer
15
16
  @creation_opts = creation_opts
16
17
  end
17
18
 
18
- def deploy(version_label, settings)
19
+ def deploy(version_label, settings={})
19
20
  terminate if @creation_opts[:phoenix_mode]
20
21
  create_or_update_env(version_label, settings)
21
22
  smoke_test
@@ -39,15 +40,6 @@ module EbDeployer
39
40
  puts "[#{Time.now.utc}][environment:#{@name}] #{msg}"
40
41
  end
41
42
 
42
- private
43
-
44
- def shorten(str, max_length, digest_length=5)
45
- raise "max length (#{max_length}) should be larger than digest_length (#{digest_length})" if max_length < digest_length
46
- return self if str.size <= max_length
47
- sha1 = Digest::SHA1.hexdigest(str)
48
- sha1[0..(digest_length - 1)] + str[(max_length - digest_length - 1)..-1]
49
- end
50
-
51
43
  def terminate
52
44
  if @bs.environment_exists?(@app, @name)
53
45
  with_polling_events(/terminateEnvironment completed successfully/i) do
@@ -56,6 +48,9 @@ module EbDeployer
56
48
  end
57
49
  end
58
50
 
51
+
52
+ private
53
+
59
54
  def create_or_update_env(version_label, settings)
60
55
  if @bs.environment_exists?(@app, @name)
61
56
  with_polling_events(/Environment update completed successfully/i) do
@@ -76,8 +71,14 @@ module EbDeployer
76
71
  def with_polling_events(terminate_pattern, &block)
77
72
  event_start_time = Time.now
78
73
  yield
79
- EventPoller.new(@app, @name, @bs).poll(event_start_time) do |event|
80
- raise event[:message] if event[:message] =~ /Failed to deploy application/
74
+ event_poller.poll(event_start_time) do |event|
75
+ if event[:message] =~ /Failed to deploy application/
76
+ raise event[:message]
77
+ end
78
+
79
+ if event[:message] =~ /Command failed on instance/
80
+ raise "Elasticbeanstalk instance provision failed (maybe a problem with your .ebextension files). The original message: #{event[:message]}"
81
+ end
81
82
 
82
83
  log_event(event)
83
84
  break if event[:message] =~ terminate_pattern
@@ -98,6 +99,10 @@ module EbDeployer
98
99
  end
99
100
  end
100
101
 
102
+ def event_poller
103
+ @event_poller || EventPoller.new(@app, @name, @bs)
104
+ end
105
+
101
106
 
102
107
  def log_event(event)
103
108
  puts "[#{event[:event_date]}][environment:#{@name}] #{event[:message]}"
@@ -1,3 +1,3 @@
1
1
  module EbDeployer
2
- VERSION = "0.3.1"
2
+ VERSION = "0.3.2"
3
3
  end
@@ -26,6 +26,7 @@ class EBStub
26
26
  raise "env name #{env} is longer than 23 chars" if env.size > 23
27
27
  raise "app not exists" unless application_exists?(app)
28
28
  @envs[env_key(app, env)] = {
29
+ :name => env,
29
30
  :application => app,
30
31
  :solution_stack => solution_stack,
31
32
  :version => version,
@@ -34,7 +35,7 @@ class EBStub
34
35
  end
35
36
 
36
37
  def delete_environment(app, env)
37
- @envs.delete(env)
38
+ @envs.delete(env_key(app, env))
38
39
  @envs_been_deleted[app] ||= []
39
40
  @envs_been_deleted[app] << env
40
41
  end
@@ -119,8 +120,8 @@ class EBStub
119
120
 
120
121
  def environment_names_for_application(app)
121
122
  @envs.inject([]) do |memo, pair|
122
- env_name, env = pair
123
- memo << env_name if env[:application] == app
123
+ key, env = pair
124
+ memo << env[:name] if env[:application] == app
124
125
  memo
125
126
  end
126
127
  end
@@ -154,6 +155,10 @@ class S3Stub
154
155
  @buckets.has_key?(bucket_name)
155
156
  end
156
157
 
158
+ def objects(bucket_name)
159
+ @buckets[bucket_name]
160
+ end
161
+
157
162
  def object_length(bucket_name, obj_name)
158
163
  @buckets[bucket_name][obj_name] && File.size(@buckets[bucket_name][obj_name])
159
164
  end
@@ -161,6 +166,7 @@ class S3Stub
161
166
  def upload_file(bucket_name, obj_name, file)
162
167
  @buckets[bucket_name][obj_name] = file
163
168
  end
169
+
164
170
  end
165
171
 
166
172
  class CFStub
data/test/deploy_test.rb CHANGED
@@ -392,6 +392,17 @@ class DeployTest < MiniTest::Unit::TestCase
392
392
  assert_equal 'simple-production', @eb_driver.environment_cname_prefix('simple', inactive_env)
393
393
  end
394
394
 
395
+ def test_pass_pathname_as_package_file
396
+ deploy(:package => Pathname.new(@sample_package),
397
+ :application => 'simple',
398
+ :environment => "production",
399
+ :package_bucket => 'thoughtworks.simple')
400
+
401
+ s3_objects = @s3_driver.objects('thoughtworks.simple.packages')
402
+ assert_equal 1, s3_objects.size
403
+ assert_equal @sample_package, s3_objects.values.first.to_s
404
+ end
405
+
395
406
  private
396
407
 
397
408
  def temp_file(content)
@@ -400,10 +411,6 @@ class DeployTest < MiniTest::Unit::TestCase
400
411
  f
401
412
  end
402
413
 
403
- def eb_envname(app_name, env_name)
404
- EbDeployer::Environment.unique_ebenv_name(app_name, env_name)
405
- end
406
-
407
414
  def query_resource_output(key, opts)
408
415
  EbDeployer.query_resource_output(key, {:bs_driver => @eb_driver,
409
416
  :s3_driver => @s3_driver,
@@ -420,7 +427,6 @@ class DeployTest < MiniTest::Unit::TestCase
420
427
  EbDeployer.destroy(opts.merge(stubs))
421
428
  end
422
429
 
423
-
424
430
  def stubs
425
431
  { :bs_driver => @eb_driver,
426
432
  :s3_driver => @s3_driver,
@@ -0,0 +1,83 @@
1
+ require 'test_helper'
2
+
3
+ class EnvironmentTest < MiniTest::Unit::TestCase
4
+ class PollerStub
5
+ class Deadloop < StandardError; end
6
+
7
+ def initialize(messages)
8
+ start_time = Time.now.utc
9
+ @events = messages.map do |message|
10
+ start_time += 1
11
+ {:event_date => start_time, :message => message}
12
+ end
13
+ end
14
+
15
+
16
+ def poll(start_time = Time.now, &block)
17
+ @events.each(&block)
18
+ raise Deadloop.new('poll will never terminate if you do not set a break in the block')
19
+ end
20
+ end
21
+
22
+ def setup
23
+ @eb_driver = EBStub.new
24
+ @eb_driver.create_application("myapp")
25
+ end
26
+
27
+ def test_deploy_should_create_corresponding_eb_env
28
+ env = EbDeployer::Environment.new("myapp", "production", @eb_driver)
29
+ env.deploy("version1")
30
+ assert @eb_driver.environment_exists?('myapp', eb_envname('myapp', 'production'))
31
+ end
32
+
33
+ def test_deploy_again_should_update_environment
34
+ env = EbDeployer::Environment.new("myapp", "production", @eb_driver)
35
+ env.deploy("version1")
36
+ env.deploy("version2")
37
+ assert @eb_driver.environment_exists?('myapp', eb_envname('myapp', 'production'))
38
+ assert_equal 'version2', @eb_driver.environment_verion_label('myapp', eb_envname('myapp', 'production'))
39
+ end
40
+
41
+ def test_option_setttings_get_set_on_eb_env
42
+ env = EbDeployer::Environment.new("myapp", "production", @eb_driver)
43
+ env.deploy("version1", {s1: 'v1'})
44
+ assert_equal({s1: 'v1' }, @eb_driver.environment_settings('myapp', eb_envname('myapp', 'production')))
45
+ end
46
+
47
+ def test_should_run_smoke_test_after_deploy
48
+ smoked_host = nil
49
+ env = EbDeployer::Environment.new("myapp", "production", @eb_driver, :smoke_test => Proc.new { |host| smoked_host = host })
50
+ env.deploy("version1")
51
+
52
+ assert !smoked_host.nil?
53
+ assert_match( /myapp.*\.elasticbeanstalk\.com/, smoked_host)
54
+ end
55
+
56
+ def test_should_raise_runtime_error_when_deploy_failed
57
+ env = EbDeployer::Environment.new("myapp", "production", @eb_driver)
58
+ env.event_poller = PollerStub.new(["start deploying", "Failed to deploy application"])
59
+ assert_raises(RuntimeError) { env.deploy("version 1") }
60
+ end
61
+
62
+ def test_should_raise_runtime_error_when_eb_extension_execution_failed
63
+ env = EbDeployer::Environment.new("myapp", "production", @eb_driver)
64
+
65
+ env.event_poller = PollerStub.new(["start deploying",
66
+ "create environment",
67
+ "Command failed on instance. Return code: 1 Output: Error occurred during build: Command hooks failed",
68
+ "Successfully launched environment"])
69
+
70
+ assert_raises(RuntimeError) { env.deploy("version 1") }
71
+ end
72
+
73
+
74
+ def test_terminate_should_delete_environment
75
+ env = EbDeployer::Environment.new("myapp", "production", @eb_driver)
76
+ env.deploy("version1")
77
+ env.terminate
78
+ assert !@eb_driver.environment_exists?('myapp', eb_envname('myapp', 'production'))
79
+ end
80
+
81
+
82
+
83
+ end
data/test/test_helper.rb CHANGED
@@ -13,4 +13,9 @@ class MiniTest::Unit::TestCase
13
13
  File.open(path, 'w') { |f| f << content }
14
14
  path
15
15
  end
16
+
17
+ def eb_envname(app_name, env_name)
18
+ EbDeployer::Environment.unique_ebenv_name(app_name, env_name)
19
+ end
20
+
16
21
  end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eb_deployer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
5
- prerelease:
4
+ version: 0.3.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - wpc
@@ -10,22 +9,20 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2014-02-05 00:00:00.000000000 Z
12
+ date: 2014-02-14 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: aws-sdk
17
16
  requirement: !ruby/object:Gem::Requirement
18
- none: false
19
17
  requirements:
20
- - - ! '>='
18
+ - - ">="
21
19
  - !ruby/object:Gem::Version
22
20
  version: '0'
23
21
  type: :runtime
24
22
  prerelease: false
25
23
  version_requirements: !ruby/object:Gem::Requirement
26
- none: false
27
24
  requirements:
28
- - - ! '>='
25
+ - - ">="
29
26
  - !ruby/object:Gem::Version
30
27
  version: '0'
31
28
  description: For automate blue green deployment flow on Elasti Beanstalk.
@@ -37,9 +34,9 @@ executables:
37
34
  extensions: []
38
35
  extra_rdoc_files: []
39
36
  files:
40
- - .gitignore
41
- - .ruby-gemset
42
- - .ruby-version
37
+ - ".gitignore"
38
+ - ".ruby-gemset"
39
+ - ".ruby-version"
43
40
  - Gemfile
44
41
  - LICENSE
45
42
  - README.md
@@ -66,32 +63,32 @@ files:
66
63
  - test/cloud_formation_provisioner_test.rb
67
64
  - test/config_loader_test.rb
68
65
  - test/deploy_test.rb
66
+ - test/environment_test.rb
69
67
  - test/smoke_test_test.rb
70
68
  - test/test_helper.rb
71
69
  homepage: https://github.com/ThoughtWorksStudios/eb_deployer
72
70
  licenses:
73
71
  - MIT
72
+ metadata: {}
74
73
  post_install_message:
75
74
  rdoc_options: []
76
75
  require_paths:
77
76
  - lib
78
77
  required_ruby_version: !ruby/object:Gem::Requirement
79
- none: false
80
78
  requirements:
81
- - - ! '>='
79
+ - - ">="
82
80
  - !ruby/object:Gem::Version
83
81
  version: '0'
84
82
  required_rubygems_version: !ruby/object:Gem::Requirement
85
- none: false
86
83
  requirements:
87
- - - ! '>='
84
+ - - ">="
88
85
  - !ruby/object:Gem::Version
89
86
  version: '0'
90
87
  requirements: []
91
88
  rubyforge_project:
92
- rubygems_version: 1.8.23
89
+ rubygems_version: 2.2.0
93
90
  signing_key:
94
- specification_version: 3
91
+ specification_version: 4
95
92
  summary: Low friction deployments should be a breeze. Elastic Beanstalk provides a
96
93
  great foundation for performing Blue-Green deployments, and EbDeployer add a missing
97
94
  top to automate the whole flow out of box.
@@ -100,6 +97,6 @@ test_files:
100
97
  - test/cloud_formation_provisioner_test.rb
101
98
  - test/config_loader_test.rb
102
99
  - test/deploy_test.rb
100
+ - test/environment_test.rb
103
101
  - test/smoke_test_test.rb
104
102
  - test/test_helper.rb
105
- has_rdoc: