eb_deployer 0.3.8 → 0.3.9

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