beanstalkify 0.0.6 → 0.0.7
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.
- data/Gemfile.lock +1 -1
- data/lib/beanstalkify/application.rb +4 -2
- data/lib/beanstalkify/environment.rb +87 -74
- data/lib/beanstalkify/version.rb +1 -1
- data/test/environment_spec.rb +69 -41
- metadata +4 -4
data/Gemfile.lock
CHANGED
@@ -18,12 +18,14 @@ module Beanstalkify
|
|
18
18
|
if env.status.empty?
|
19
19
|
puts "Creating stack '#{@stack}' for #{archive.app_name}-#{archive.version}..."
|
20
20
|
env.create!(archive, @stack, @cnames, @config)
|
21
|
-
env.
|
21
|
+
env.wait_until_status_is_not "Launching"
|
22
22
|
else
|
23
23
|
puts "Deploying #{archive.version} to #{env.name}..."
|
24
24
|
env.deploy!(archive, @config)
|
25
|
-
env.
|
25
|
+
env.wait_until_status_is_not "Updating"
|
26
26
|
end
|
27
|
+
|
28
|
+
env.wait_until_healthy
|
27
29
|
puts "Done. Visit http://#{env.url} in your browser."
|
28
30
|
DeploymentInfo.new env, archive
|
29
31
|
end
|
@@ -1,85 +1,98 @@
|
|
1
1
|
require 'beanstalkify/beanstalk'
|
2
2
|
|
3
3
|
module Beanstalkify
|
4
|
-
|
5
|
-
|
4
|
+
class Environment
|
5
|
+
POLL_INTERVAL = 5
|
6
|
+
STATUS_CHANGE_TIMEOUT = 1200
|
7
|
+
HEALTHY_TIMEOUT = 120
|
8
|
+
|
9
|
+
attr_accessor :name
|
6
10
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
# Assuming the provided app has already been uploaded,
|
13
|
-
# update this environment to the app's version
|
14
|
-
# Optionally pass in a bunch of settings to override
|
15
|
-
def deploy!(app, settings=[])
|
16
|
-
@beanstalk.update_environment({
|
17
|
-
:version_label => app.version,
|
18
|
-
:environment_name => self.name,
|
19
|
-
:option_settings => settings
|
20
|
-
})
|
21
|
-
end
|
22
|
-
|
23
|
-
# Assuming the archive has already been uploaded,
|
24
|
-
# create a new environment with the app deployed onto the provided stack.
|
25
|
-
# Attempts to use the first available cname in the cnames array.
|
26
|
-
def create!(archive, stack, cnames, settings=[])
|
27
|
-
params = {
|
28
|
-
:application_name => archive.app_name,
|
29
|
-
:version_label => archive.version,
|
30
|
-
:environment_name => self.name,
|
31
|
-
:solution_stack_name => stack,
|
32
|
-
:option_settings => settings
|
33
|
-
}
|
34
|
-
cnames.each do |c|
|
35
|
-
if dns_available(c)
|
36
|
-
params[:cname_prefix] = c
|
37
|
-
break
|
38
|
-
else
|
39
|
-
puts "CNAME #{c} is unavailable."
|
40
|
-
end
|
41
|
-
end
|
42
|
-
@beanstalk.create_environment(params)
|
43
|
-
end
|
11
|
+
def initialize(archive, name)
|
12
|
+
@name = [archive.app_name, name].join("-")
|
13
|
+
@beanstalk = Beanstalk.api
|
14
|
+
end
|
44
15
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
16
|
+
# Assuming the provided app has already been uploaded,
|
17
|
+
# update this environment to the app's version
|
18
|
+
# Optionally pass in a bunch of settings to override
|
19
|
+
def deploy!(app, settings=[])
|
20
|
+
@beanstalk.update_environment({
|
21
|
+
version_label: app.version,
|
22
|
+
environment_name: self.name,
|
23
|
+
option_settings: settings
|
24
|
+
})
|
25
|
+
end
|
50
26
|
|
51
|
-
|
52
|
-
|
53
|
-
|
27
|
+
# Assuming the archive has already been uploaded,
|
28
|
+
# create a new environment with the app deployed onto the provided stack.
|
29
|
+
# Attempts to use the first available cname in the cnames array.
|
30
|
+
def create!(archive, stack, cnames, settings=[])
|
31
|
+
params = {
|
32
|
+
application_name: archive.app_name,
|
33
|
+
version_label: archive.version,
|
34
|
+
environment_name: self.name,
|
35
|
+
solution_stack_name: stack,
|
36
|
+
option_settings: settings
|
37
|
+
}
|
38
|
+
cnames.each do |c|
|
39
|
+
if dns_available(c)
|
40
|
+
params[:cname_prefix] = c
|
41
|
+
break
|
42
|
+
else
|
43
|
+
puts "CNAME #{c} is unavailable."
|
54
44
|
end
|
45
|
+
end
|
46
|
+
@beanstalk.create_environment(params)
|
47
|
+
end
|
55
48
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
def healthy?
|
62
|
-
e = describe_environment
|
63
|
-
e ? e[:health] == 'Green' : false
|
64
|
-
end
|
49
|
+
def dns_available(cname)
|
50
|
+
@beanstalk.check_dns_availability({
|
51
|
+
cname_prefix: cname
|
52
|
+
})[:available]
|
53
|
+
end
|
65
54
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
55
|
+
def url
|
56
|
+
e = describe_environment
|
57
|
+
e ? e[:cname] : ""
|
58
|
+
end
|
59
|
+
|
60
|
+
def healthy?
|
61
|
+
e = describe_environment
|
62
|
+
e ? e[:health] == 'Green' : false
|
63
|
+
end
|
64
|
+
|
65
|
+
def status
|
66
|
+
e = describe_environment
|
67
|
+
e ? e[:status] : ""
|
68
|
+
end
|
69
|
+
|
70
|
+
def wait_until_status_is_not(old_status)
|
71
|
+
puts "Waiting for #{self.name} to finish #{old_status.downcase}..."
|
72
|
+
wait_until -> { status != old_status }, STATUS_CHANGE_TIMEOUT
|
73
|
+
end
|
74
|
+
|
75
|
+
def wait_until_healthy
|
76
|
+
puts "Waiting until #{self.name} is healthy..."
|
77
|
+
wait_until -> { healthy? }, HEALTHY_TIMEOUT
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def describe_environment
|
83
|
+
@beanstalk.describe_environments({
|
84
|
+
environment_names: [name],
|
85
|
+
include_deleted: false
|
86
|
+
}).data[:environments].first
|
87
|
+
end
|
88
|
+
|
89
|
+
def wait_until(condition, timeout)
|
90
|
+
until condition.call or timeout <= 0
|
91
|
+
print '.'
|
92
|
+
sleep POLL_INTERVAL
|
93
|
+
timeout -= POLL_INTERVAL
|
94
|
+
end
|
95
|
+
puts
|
84
96
|
end
|
97
|
+
end
|
85
98
|
end
|
data/lib/beanstalkify/version.rb
CHANGED
data/test/environment_spec.rb
CHANGED
@@ -6,49 +6,28 @@ describe Beanstalkify::Environment do
|
|
6
6
|
allow(Beanstalkify::Beanstalk).to receive(:api).and_return @beanstalk_api = double
|
7
7
|
@archive = Beanstalkify::Archive.new '/path/to/my/archive/app-name-version.zip'
|
8
8
|
@env = Beanstalkify::Environment.new @archive, "Test"
|
9
|
+
@settings = {something: 'enabled'}
|
9
10
|
end
|
11
|
+
|
12
|
+
describe 'creation' do
|
13
|
+
it 'creates a new environment with params' do
|
14
|
+
expect_beanstalk_create_environment
|
15
|
+
@env.create! @archive, 'mastack', [], @settings
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'when a CNAME is specified' do
|
19
|
+
it 'creates a new environment with a cname, if available' do
|
20
|
+
when_beanstalk_cname_availability_is 'ma-cname-1', true
|
21
|
+
expect_beanstalk_create_environment(cname_prefix: 'ma-cname-1')
|
22
|
+
@env.create! @archive, 'mastack', ['ma-cname-1'], @settings
|
23
|
+
end
|
10
24
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
:solution_stack_name => 'mastack',
|
18
|
-
:option_settings => masettings
|
19
|
-
).and_return nil
|
20
|
-
@env.create! @archive, 'mastack', [], masettings
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'creates a new environment with a cname, if available' do
|
24
|
-
masettings = {}
|
25
|
-
expect(@beanstalk_api).to receive(:create_environment).with(
|
26
|
-
:application_name => 'app-name',
|
27
|
-
:version_label => 'version',
|
28
|
-
:environment_name => 'app-name-Test',
|
29
|
-
:solution_stack_name => 'mastack',
|
30
|
-
:cname_prefix => 'ma-cname-1',
|
31
|
-
:option_settings => masettings
|
32
|
-
).and_return nil
|
33
|
-
expect(@beanstalk_api).to receive(:check_dns_availability).and_return(
|
34
|
-
:available => true
|
35
|
-
)
|
36
|
-
@env.create! @archive, 'mastack', ['ma-cname-1'], masettings
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'creates an environment without the cname, if the cname was unavailable' do
|
40
|
-
masettings = {}
|
41
|
-
expect(@beanstalk_api).to receive(:create_environment).with(
|
42
|
-
:application_name => 'app-name',
|
43
|
-
:version_label => 'version',
|
44
|
-
:environment_name => 'app-name-Test',
|
45
|
-
:solution_stack_name => 'mastack',
|
46
|
-
:option_settings => masettings
|
47
|
-
).and_return nil
|
48
|
-
expect(@beanstalk_api).to receive(:check_dns_availability).and_return(
|
49
|
-
:available => false
|
50
|
-
)
|
51
|
-
@env.create! @archive, 'mastack', ['ma-cname-1'], masettings
|
25
|
+
it 'creates an environment without the cname, if the cname was unavailable' do
|
26
|
+
when_beanstalk_cname_availability_is 'ma-cname-1', false
|
27
|
+
expect_beanstalk_create_environment
|
28
|
+
@env.create! @archive, 'mastack', ['ma-cname-1'], @settings
|
29
|
+
end
|
30
|
+
end
|
52
31
|
end
|
53
32
|
|
54
33
|
it 'prepends the application name because environment names must be unique within an AWS account' do
|
@@ -72,6 +51,40 @@ describe Beanstalkify::Environment do
|
|
72
51
|
@env.should be_healthy
|
73
52
|
end
|
74
53
|
|
54
|
+
describe 'waiting for a Beanstalk status change' do
|
55
|
+
before(:each) do
|
56
|
+
@env.stub :sleep
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'waits for the value to be different' do
|
60
|
+
expect(@env).to receive(:status).exactly(3).times.and_return 'Launching', 'Launching', 'Running'
|
61
|
+
@env.wait_until_status_is_not 'Launching'
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'times out after a while but does not throw an error' do
|
65
|
+
attempts = (Beanstalkify::Environment::STATUS_CHANGE_TIMEOUT / Beanstalkify::Environment::POLL_INTERVAL) + 1
|
66
|
+
expect(@env).to receive(:status).exactly(attempts).times.and_return 'Unchanged'
|
67
|
+
@env.wait_until_status_is_not 'Unchanged'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe 'waiting until healthy' do
|
72
|
+
before(:each) do
|
73
|
+
@env.stub :sleep
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'waits until health is green' do
|
77
|
+
expect(@env).to receive(:healthy?).exactly(3).times.and_return false, false, true
|
78
|
+
@env.wait_until_healthy
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'times out after a while but does not throw an error' do
|
82
|
+
attempts = (Beanstalkify::Environment::HEALTHY_TIMEOUT / Beanstalkify::Environment::POLL_INTERVAL) + 1
|
83
|
+
expect(@env).to receive(:healthy?).exactly(attempts).times.and_return false
|
84
|
+
@env.wait_until_healthy
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
75
88
|
def when_beanstalk_describe_environments_returns(env_data)
|
76
89
|
expect(@beanstalk_api).to receive(:describe_environments).with(
|
77
90
|
environment_names: ["app-name-Test"],
|
@@ -80,4 +93,19 @@ describe Beanstalkify::Environment do
|
|
80
93
|
data: {environments: [env_data]}
|
81
94
|
)
|
82
95
|
end
|
96
|
+
|
97
|
+
def expect_beanstalk_create_environment(additional_opts={})
|
98
|
+
opts = {
|
99
|
+
application_name: 'app-name',
|
100
|
+
version_label: 'version',
|
101
|
+
environment_name: 'app-name-Test',
|
102
|
+
solution_stack_name: 'mastack',
|
103
|
+
option_settings: @settings
|
104
|
+
}.merge additional_opts
|
105
|
+
expect(@beanstalk_api).to receive(:create_environment).with(opts).and_return nil
|
106
|
+
end
|
107
|
+
|
108
|
+
def when_beanstalk_cname_availability_is(cname_prefix, available)
|
109
|
+
expect(@beanstalk_api).to receive(:check_dns_availability).with(cname_prefix: cname_prefix).and_return(available: available)
|
110
|
+
end
|
83
111
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: beanstalkify
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-08-
|
12
|
+
date: 2013-08-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: aws-sdk
|
@@ -83,7 +83,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
83
83
|
version: '0'
|
84
84
|
segments:
|
85
85
|
- 0
|
86
|
-
hash:
|
86
|
+
hash: 2119341935535763932
|
87
87
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
88
|
none: false
|
89
89
|
requirements:
|
@@ -92,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
92
|
version: '0'
|
93
93
|
segments:
|
94
94
|
- 0
|
95
|
-
hash:
|
95
|
+
hash: 2119341935535763932
|
96
96
|
requirements: []
|
97
97
|
rubyforge_project:
|
98
98
|
rubygems_version: 1.8.24
|