eb_deployer 0.3.8 → 0.3.9

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 CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: adfb84fcb5cfc542a7dbd3634358739b9db48283
4
- data.tar.gz: 46dd232647393e435ff65b2cab8ecdfe82de6f54
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZTFkZGMyNGQ3YTg2ZjRjMGM1ZTE0OGIwMDk5ZTQ0ZDgwY2MyMWJhNw==
5
+ data.tar.gz: !binary |-
6
+ YmZkZmQ3MTFiZDQ2YjQxMjg4OWM0NWZmMzk3MzZiOTY2YmM5MzdlZQ==
5
7
  SHA512:
6
- metadata.gz: d3cc4a4ec8d89f9046ec54d22f95b0d65585b7c3404c2904cd4473180ea945ca868ecef15acc9c57c9b58ef79bfee2d26d8831be8aa08d564188721a59175691
7
- data.tar.gz: 0870b0bc37619d8f65837b10820a3ac9cfd64ab84f601f052402a12a4467687f544a624d34996ccedd4c2a5fa399c040ffccbcd44bf765d6392b472e94886e97
8
+ metadata.gz: !binary |-
9
+ YTAxZjdhNmEwZTcwMjYyNzA2MzY1Zjg5ZDM2ZDhiNmQzN2M1Y2M0Mjk0ZjQy
10
+ YTczYzEzNDQ1ODAxMTkwOTVlZTc5YmQwZDkxN2JkY2IwNmVmY2U4MWUzMzEx
11
+ Y2JlMGJjMmI3ZTJiZjQ1OWM5Yzk3NTcyMTdlNmMzMDYyMGY5NjE=
12
+ data.tar.gz: !binary |-
13
+ ZTE5MjFiODhmNjA0MjFmNmQyMTJhMmYwMWRiYjM1ODdlNWYyOWMxYzExZTZi
14
+ OTY1ZmI2ZjkyMjA5ZGM0NTQzMTQ1MTkwZjI3MjY5N2UyOTQyNjRiZTc2OTk3
15
+ ZWVmNDQxNTcxNDk5ZTljMGE5YjdlMDZiM2M4NmQxMmMxYjVjNDM=
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ 0.3.9
2
+ ====
3
+ * Fix hang problem introduced in 0.3.8 when migrating old ElasticBeanstalk environment.
4
+ * Fix issue #13 (Deployment via S3 object broken since 0.3.7)
5
+
1
6
  0.3.8
2
7
  =====
3
8
  * Change ElasticBeanstalk environment name pattern. Stop using sufix hash to make eb environment global unique. (Because ElasticBeanstalk does not require environment has globally uniqe name any more.)
@@ -36,7 +36,6 @@ module EbDeployer
36
36
 
37
37
  def delete(env_name=nil)
38
38
  if @eb_driver.application_exists?(@name)
39
- env_name = EbEnvironment.unique_ebenv_name(@name, env_name) unless env_name.nil?
40
39
  available_envs = @eb_driver.environment_names_for_application(@name)
41
40
 
42
41
  unless env_name.nil? || available_envs.include?(env_name)
@@ -62,6 +62,7 @@ module EbDeployer
62
62
 
63
63
  def package_digest(package)
64
64
  return nil unless package
65
+ return package unless File.exists?(package)
65
66
  Digest::MD5.file(package).hexdigest
66
67
  end
67
68
  end
@@ -6,29 +6,29 @@ module EbDeployer
6
6
  end
7
7
 
8
8
  def deploy(version_label, env_settings)
9
- if !envs.any?(&method(:active_env?))
10
- env('a', @env.cname_prefix).
9
+ if !ebenvs.any?(&method(:active_ebenv?))
10
+ ebenv('a', @env.cname_prefix).
11
11
  deploy(version_label, env_settings)
12
12
  return
13
13
  end
14
14
 
15
- active_env = envs.detect(&method(:active_env?))
16
- inactive_env = envs.reject(&method(:active_env?)).first
15
+ active_ebenv = ebenvs.detect(&method(:active_ebenv?))
16
+ inactive_ebenv = ebenvs.reject(&method(:active_ebenv?)).first
17
17
 
18
- inactive_env.deploy(version_label, env_settings)
19
- active_env.swap_cname_with(inactive_env)
18
+ inactive_ebenv.deploy(version_label, env_settings)
19
+ active_ebenv.swap_cname_with(inactive_ebenv)
20
20
  end
21
21
 
22
22
  private
23
- def active_env?(env)
24
- env.cname_prefix == @env.cname_prefix
23
+ def active_ebenv?(ebenv)
24
+ ebenv.cname_prefix == @env.cname_prefix
25
25
  end
26
26
 
27
- def envs
28
- [env('a'), env('b')]
27
+ def ebenvs
28
+ [ebenv('a'), ebenv('b')]
29
29
  end
30
30
 
31
- def env(suffix, cname_prefix=nil)
31
+ def ebenv(suffix, cname_prefix=nil)
32
32
  @env.new_eb_env(suffix, cname_prefix || inactive_cname_prefix)
33
33
  end
34
34
 
@@ -1,6 +1,6 @@
1
1
  module EbDeployer
2
2
  class EbEnvironment
3
- attr_reader :app, :name
3
+ attr_reader :app, :name, :legacy_env_name
4
4
  attr_writer :event_poller
5
5
 
6
6
  def self.legacy_ebenv_name(app_name, env_name)
@@ -13,6 +13,7 @@ module EbDeployer
13
13
  @name = name
14
14
  @bs = eb_driver
15
15
  @creation_opts = creation_opts
16
+ @legacy_env_name = self.class.legacy_ebenv_name(@app, @name)
16
17
  end
17
18
 
18
19
  def deploy(version_label, settings={})
@@ -24,16 +25,12 @@ module EbDeployer
24
25
  end
25
26
 
26
27
  def cname_prefix
27
- @bs.environment_cname_prefix(@app, @name)
28
- end
29
-
30
- def ==(another)
31
- self.app == another.app && self.name == another.name
28
+ @bs.environment_cname_prefix(@app, defactor_env_name)
32
29
  end
33
30
 
34
31
  def swap_cname_with(another)
35
32
  log("Swap CNAME with env #{another.name}")
36
- @bs.environment_swap_cname(self.app, self.name, another.name)
33
+ @bs.environment_swap_cname(self.app, self.defactor_env_name, another.defactor_env_name)
37
34
  end
38
35
 
39
36
  def log(msg)
@@ -41,34 +38,37 @@ module EbDeployer
41
38
  end
42
39
 
43
40
  def terminate
44
- terminate_environment(@name)
41
+ env_name = defactor_env_name
42
+ if @bs.environment_exists?(@app, env_name)
43
+ with_polling_events(env_name, /terminateEnvironment completed successfully/i) do
44
+ @bs.delete_environment(@app, env_name)
45
+ end
46
+ end
47
+ end
48
+
49
+ def defactor_env_name
50
+ @bs.environment_exists?(@app, @legacy_env_name) ? @legacy_env_name : @name
45
51
  end
46
52
 
47
53
  private
48
54
 
49
55
  def terminate_legacy_env
50
- legacy_env_name = self.class.legacy_ebenv_name(@app, @name)
51
- if @bs.environment_exists?(@app, legacy_env_name)
52
- log("Found legacy environment '#{legacy_env_name}', eb_deployer will terminate it and create new environment following new name pattern.")
53
- terminate_environment(legacy_env_name)
54
- end
55
- end
56
+ if @bs.environment_exists?(@app, @legacy_env_name)
57
+ log("Found legacy environment '#{@legacy_env_name}', eb_deployer will terminate it and create new environment following new name pattern as '#{@name}'.")
56
58
 
57
- def terminate_environment(env_name)
58
- if @bs.environment_exists?(@app, env_name)
59
- with_polling_events(/terminateEnvironment completed successfully/i) do
60
- @bs.delete_environment(@app, env_name)
59
+ with_polling_events(@legacy_env_name, /terminateEnvironment completed successfully/i) do
60
+ @bs.delete_environment(@app, @legacy_env_name)
61
61
  end
62
62
  end
63
63
  end
64
64
 
65
65
  def create_or_update_env(version_label, settings)
66
66
  if @bs.environment_exists?(@app, @name)
67
- with_polling_events(/Environment update completed successfully/i) do
67
+ with_polling_events(@name, /Environment update completed successfully/i) do
68
68
  @bs.update_environment(@app, @name, version_label, @creation_opts[:tier], settings)
69
69
  end
70
70
  else
71
- with_polling_events(/Successfully launched environment/i) do
71
+ with_polling_events(@name, /Successfully launched environment/i) do
72
72
  @bs.create_environment(@app, @name, @creation_opts[:solution_stack], @creation_opts[:cname_prefix], version_label, @creation_opts[:tier], settings)
73
73
  end
74
74
  end
@@ -79,10 +79,10 @@ module EbDeployer
79
79
  SmokeTest.new(@creation_opts[:smoke_test]).run(host_name, self)
80
80
  end
81
81
 
82
- def with_polling_events(terminate_pattern, &block)
82
+ def with_polling_events(env_name, terminate_pattern, &block)
83
83
  event_start_time = Time.now
84
84
  yield
85
- event_poller.poll(event_start_time) do |event|
85
+ event_poller.poll(env_name, event_start_time) do |event|
86
86
  if event[:message] =~ /Failed to deploy application/
87
87
  raise event[:message]
88
88
  end
@@ -111,7 +111,7 @@ module EbDeployer
111
111
  end
112
112
 
113
113
  def event_poller
114
- @event_poller || EventPoller.new(@app, @name, @bs)
114
+ @event_poller || EventPoller.new(@app, @bs)
115
115
  end
116
116
 
117
117
 
@@ -1,13 +1,13 @@
1
1
  module EbDeployer
2
2
  class EventPoller
3
- def initialize(app, env, beanstalk)
4
- @app, @env, @beanstalk = app, env, beanstalk
3
+ def initialize(app, beanstalk)
4
+ @app, @beanstalk = app, beanstalk
5
5
  end
6
6
 
7
- def poll(start_time = Time.now, &block)
7
+ def poll(eb_env_name, start_time = Time.now, &block)
8
8
  handled = Set.new
9
9
  loop do
10
- fetch_events(start_time) do |events|
10
+ fetch_events(eb_env_name, start_time) do |events|
11
11
  new_events = events.reject { |e| handled.include?(digest(e)) }
12
12
  handle(new_events, &block)
13
13
  handled += new_events.map { |e| digest(e) }
@@ -27,14 +27,14 @@ module EbDeployer
27
27
  events.reverse.each(&block)
28
28
  end
29
29
 
30
- def fetch_events(start_time, &block)
31
- events, next_token = @beanstalk.fetch_events(@app, @env, :start_time => start_time.iso8601)
30
+ def fetch_events(eb_env_name, start_time, &block)
31
+ events, next_token = @beanstalk.fetch_events(@app, eb_env_name, :start_time => start_time.iso8601)
32
32
  yield(events)
33
- fetch_next(next_token, &block) if next_token
33
+ fetch_next(eb_env_name, next_token, &block) if next_token
34
34
  end
35
35
 
36
- def fetch_next(next_token, &block)
37
- events, next_token = @beanstalk.fetch_events(@app, @env, :next_token => next_token)
36
+ def fetch_next(eb_env_name, next_token, &block)
37
+ events, next_token = @beanstalk.fetch_events(@app, eb_env_name, :next_token => next_token)
38
38
  yield(events)
39
39
  fetch_next(next_token, &block) if next_token
40
40
  end
@@ -1,3 +1,3 @@
1
1
  module EbDeployer
2
- VERSION = "0.3.8"
2
+ VERSION = "0.3.9"
3
3
  end
data/lib/eb_deployer.rb CHANGED
@@ -223,9 +223,10 @@ module EbDeployer
223
223
  end
224
224
 
225
225
  app = opts[:application]
226
- bs = opts[:bs_driver] || Beanstalk.new
227
- s3 = opts[:s3_driver] || S3Driver.new
228
- cf = opts[:cf_driver] || CloudFormationDriver.new
226
+ bs = opts[:bs_driver] || AWSDriver::Beanstalk.new
227
+ s3 = opts[:s3_driver] || AWSDriver::S3Driver.new
228
+ cf = opts[:cf_driver] || AWSDriver::CloudFormationDriver.new
229
+
229
230
  Application.new(app, bs, s3).delete(opts[:environment])
230
231
  end
231
232
 
@@ -308,6 +309,7 @@ module EbDeployer
308
309
  puts "YAML package file format:"
309
310
  puts "s3_bucket: <bucket_name>"
310
311
  puts "s3_key: <object_path>"
312
+ exit(0)
311
313
  end
312
314
  end
313
315
  end
@@ -1,4 +1,5 @@
1
1
  class EBStub
2
+ attr_reader :envs
2
3
  def initialize
3
4
  @apps = []
4
5
  @envs = {}
@@ -78,16 +79,16 @@ class EBStub
78
79
  end
79
80
 
80
81
  def fetch_events(app_name, env_name, options={})
81
- [[{:event_date => Time.now.utc,
82
- :message => 'Environment update completed successfully'},
83
- {:event_date => Time.now.utc,
84
- :message => 'terminateEnvironment completed successfully'},
85
- {:event_date => Time.now.utc,
86
- :message => 'Successfully launched environment'}
87
- ],
88
- nil]
82
+ unless @events # unrestricted mode for testing if no explicit events set
83
+ return generate_event_from_messages(['Environment update completed successfully',
84
+ 'terminateEnvironment completed successfully',
85
+ 'Successfully launched environment'])
86
+ end
87
+
88
+ @events[env_key(app_name, env_name)]
89
89
  end
90
90
 
91
+
91
92
  def environment_cname_prefix(app_name, env_name)
92
93
  return unless @envs[env_key(app_name, env_name)]
93
94
  @envs[env_key(app_name, env_name)][:cname_prefix] || app_name + "-" + SecureRandom.hex
@@ -140,8 +141,20 @@ class EBStub
140
141
  @versions_deleted[app_name]
141
142
  end
142
143
 
144
+ def set_events(app_name, env_name, messages)
145
+ @events ||= {}
146
+ @events[env_key(app_name, env_name)] = generate_event_from_messages(messages)
147
+ end
148
+
143
149
  private
144
150
 
151
+ def generate_event_from_messages(messages)
152
+ [messages.reverse.map do |m|
153
+ {:event_date => Time.now.utc,
154
+ :message => m}
155
+ end, nil]
156
+ end
157
+
145
158
  def env_key(app, name)
146
159
  [app, name].join("-")
147
160
  end
@@ -0,0 +1,106 @@
1
+ require 'deploy_test'
2
+
3
+ class BlueGreenDeployTest < DeployTest
4
+ def test_blue_green_deployment_strategy_should_create_blue_env_on_first_deployment
5
+ deploy(:application => 'simple',
6
+ :environment => "production",
7
+ :strategy => 'blue-green',
8
+ :version_label => 42)
9
+
10
+ assert @eb_driver.environment_exists?('simple', 'production-a')
11
+ assert_equal 'simple-production', @eb_driver.environment_cname_prefix('simple', 'production-a')
12
+ end
13
+
14
+
15
+ def test_blue_green_deployment_should_create_green_env_if_blue_exists
16
+ deploy(:application => 'simple',
17
+ :environment => "production",
18
+ :strategy => 'blue-green',
19
+ :version_label => 42)
20
+
21
+ deploy(:application => 'simple',
22
+ :environment => "production",
23
+ :strategy => 'blue-green',
24
+ :version_label => 43)
25
+
26
+ assert @eb_driver.environment_exists?('simple', 'production-a')
27
+ assert @eb_driver.environment_exists?('simple', 'production-b')
28
+ end
29
+
30
+
31
+ def test_blue_green_deployment_should_swap_cname_to_make_active_most_recent_updated_env
32
+ deploy(:application => 'simple',
33
+ :environment => "production",
34
+ :strategy => 'blue-green',
35
+ :version_label => 42)
36
+
37
+ deploy(:application => 'simple',
38
+ :environment => "production",
39
+ :strategy => 'blue-green',
40
+ :version_label => 43)
41
+
42
+ assert_match(/simple-production-inactive/, @eb_driver.environment_cname_prefix('simple', 'production-a'))
43
+
44
+ assert_equal 'simple-production', @eb_driver.environment_cname_prefix('simple', 'production-b')
45
+
46
+
47
+ deploy(:application => 'simple',
48
+ :environment => "production",
49
+ :strategy => 'blue-green',
50
+ :version_label => 44)
51
+
52
+ assert_match(/simple-production-inactive/, @eb_driver.environment_cname_prefix('simple', 'production-b'))
53
+
54
+ assert_equal 'simple-production', @eb_driver.environment_cname_prefix('simple', 'production-a')
55
+ end
56
+
57
+
58
+ def test_blue_green_deploy_should_run_smoke_test_before_cname_switch
59
+ smoked_host = []
60
+ smoke_test = lambda { |host| smoked_host << host }
61
+ [42, 43, 44].each do |version_label|
62
+ deploy(:application => 'simple',
63
+ :environment => "production",
64
+ :strategy => 'blue-green',
65
+ :smoke_test => smoke_test,
66
+ :version_label => version_label)
67
+ end
68
+
69
+ assert_equal ['simple-production.elasticbeanstalk.com',
70
+ 'simple-production-inactive.elasticbeanstalk.com',
71
+ 'simple-production-inactive.elasticbeanstalk.com'], smoked_host
72
+ end
73
+
74
+
75
+ def test_blue_green_deployment_should_delete_and_recreate_inactive_env_if_phoenix_mode_is_enabled
76
+ deploy(:application => 'simple',
77
+ :environment => "production",
78
+ :strategy => 'blue-green',
79
+ :version_label => 42,
80
+ :phoenix_mode => true)
81
+
82
+ deploy(:application => 'simple',
83
+ :environment => "production",
84
+ :strategy => 'blue-green',
85
+ :version_label => 43,
86
+ :phoenix_mode => true)
87
+
88
+ assert_equal [], @eb_driver.environments_been_deleted('simple')
89
+
90
+ inactive_env = 'production-a'
91
+ assert_match(/inactive/, @eb_driver.environment_cname_prefix('simple', inactive_env))
92
+
93
+
94
+ deploy(:application => 'simple',
95
+ :environment => "production",
96
+ :strategy => 'blue-green',
97
+ :version_label => 44,
98
+ :phoenix_mode => true)
99
+
100
+ assert_equal [inactive_env], @eb_driver.environments_been_deleted('simple')
101
+
102
+ assert_equal 'simple-production', @eb_driver.environment_cname_prefix('simple', inactive_env)
103
+ end
104
+
105
+
106
+ end
@@ -25,6 +25,19 @@ YAML
25
25
  assert_equal(nil, config[:common])
26
26
  end
27
27
 
28
+ def test_use_package_as_version_label_when_using_s3_obj_as_package
29
+ config = @loader.load(generate_input(<<-YAML, :package => 'bucket:obj'))
30
+ application: myapp
31
+ common:
32
+ strategy: inplace-update
33
+ environments:
34
+ dev:
35
+ YAML
36
+ assert_equal('myapp', config[:application])
37
+ assert_equal('bucket:obj', config[:package])
38
+ assert_equal('bucket:obj', config[:version_label])
39
+ end
40
+
28
41
  def test_common_settings_get_merge_into_the_config
29
42
  config = @loader.load(generate_input(<<-YAML))
30
43
  application: myapp