engineyard-serverside 2.5.0.cs6 → 2.5.0
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/lib/engineyard-serverside/cli.rb +25 -16
- data/lib/engineyard-serverside/configuration.rb +0 -1
- data/lib/engineyard-serverside/deploy.rb +3 -2
- data/lib/engineyard-serverside/maintenance.rb +12 -3
- data/lib/engineyard-serverside/paths.rb +13 -4
- data/lib/engineyard-serverside/rails_assets.rb +3 -11
- data/lib/engineyard-serverside/shell.rb +1 -0
- data/lib/engineyard-serverside/spawner.rb +1 -1
- data/lib/engineyard-serverside/version.rb +1 -1
- data/spec/archive_deploy_spec.rb +0 -1
- data/spec/custom_deploy_spec.rb +21 -34
- data/spec/deploy_hook_spec.rb +11 -8
- data/spec/git_strategy_spec.rb +1 -1
- data/spec/maintenance_spec.rb +44 -0
- data/spec/spec_helper.rb +55 -23
- data/spec/support/timecop.rb +5 -0
- metadata +12 -5
|
@@ -57,23 +57,28 @@ module EY
|
|
|
57
57
|
verbose_option
|
|
58
58
|
desc "enable_maintenance", "Enable maintenance page (disables web access)"
|
|
59
59
|
def enable_maintenance
|
|
60
|
-
options = self.options.dup
|
|
61
|
-
options[:release_path] = Pathname.new("/data/#{options[:app]}/current").realpath.to_s
|
|
62
|
-
|
|
63
60
|
init_and_propagate(options, 'enable_maintenance') do |servers, config, shell|
|
|
64
61
|
EY::Serverside::Maintenance.new(servers, config, shell).manually_enable
|
|
65
62
|
end
|
|
66
63
|
end
|
|
67
64
|
|
|
65
|
+
account_app_env_options
|
|
66
|
+
config_option
|
|
67
|
+
instances_options
|
|
68
|
+
verbose_option
|
|
69
|
+
desc "maintenance_status", "Maintenance status"
|
|
70
|
+
def maintenance_status
|
|
71
|
+
init(options, "maintenance-status") do |servers, config, shell|
|
|
72
|
+
EY::Serverside::Maintenance.new(servers, config, shell).status
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
68
76
|
account_app_env_options
|
|
69
77
|
config_option
|
|
70
78
|
instances_options
|
|
71
79
|
verbose_option
|
|
72
80
|
desc "disable_maintenance", "Disable maintenance page (enables web access)"
|
|
73
81
|
def disable_maintenance
|
|
74
|
-
options = self.options.dup
|
|
75
|
-
options[:release_path] = Pathname.new("/data/#{options[:app]}/current").realpath.to_s
|
|
76
|
-
|
|
77
82
|
init_and_propagate(options, 'disable_maintenance') do |servers, config, shell|
|
|
78
83
|
EY::Serverside::Maintenance.new(servers, config, shell).manually_disable
|
|
79
84
|
end
|
|
@@ -94,7 +99,7 @@ module EY
|
|
|
94
99
|
verbose_option
|
|
95
100
|
desc "hook [NAME]", "Run a particular deploy hook"
|
|
96
101
|
def hook(hook_name)
|
|
97
|
-
init(options, "hook-#{hook_name}") do |config, shell|
|
|
102
|
+
init(options, "hook-#{hook_name}") do |servers, config, shell|
|
|
98
103
|
EY::Serverside::DeployHook.new(config, shell, hook_name).call
|
|
99
104
|
end
|
|
100
105
|
end
|
|
@@ -159,8 +164,7 @@ module EY
|
|
|
159
164
|
private
|
|
160
165
|
|
|
161
166
|
def init_and_propagate(*args)
|
|
162
|
-
init(*args) do |config, shell|
|
|
163
|
-
servers = load_servers(config, shell)
|
|
167
|
+
init(*args) do |servers, config, shell|
|
|
164
168
|
propagate(servers, shell)
|
|
165
169
|
yield servers, config, shell
|
|
166
170
|
end
|
|
@@ -173,8 +177,9 @@ module EY
|
|
|
173
177
|
:log_path => File.join(ENV['HOME'], "#{config.app}-#{action}.log")
|
|
174
178
|
)
|
|
175
179
|
shell.debug "Initializing #{About.name_with_version}."
|
|
180
|
+
servers = load_servers(config, shell)
|
|
176
181
|
begin
|
|
177
|
-
yield config, shell
|
|
182
|
+
yield servers, config, shell
|
|
178
183
|
rescue EY::Serverside::RemoteFailure => e
|
|
179
184
|
shell.exception "#{e.message}"
|
|
180
185
|
raise
|
|
@@ -209,13 +214,17 @@ module EY
|
|
|
209
214
|
end
|
|
210
215
|
|
|
211
216
|
def assemble_instance_hashes(config)
|
|
212
|
-
options[:instances]
|
|
213
|
-
|
|
214
|
-
:
|
|
215
|
-
|
|
216
|
-
|
|
217
|
+
if options[:instances]
|
|
218
|
+
options[:instances].collect { |hostname|
|
|
219
|
+
{ :hostname => hostname,
|
|
220
|
+
:roles => options[:instance_roles][hostname].to_s.split(','),
|
|
221
|
+
:name => options[:instance_names][hostname],
|
|
222
|
+
:user => config.user,
|
|
223
|
+
}
|
|
217
224
|
}
|
|
218
|
-
|
|
225
|
+
else
|
|
226
|
+
[]
|
|
227
|
+
end
|
|
219
228
|
end
|
|
220
229
|
|
|
221
230
|
end
|
|
@@ -77,7 +77,6 @@ module EY
|
|
|
77
77
|
|
|
78
78
|
def_option :precompile_assets, 'detect'
|
|
79
79
|
def_option :precompile_assets_task, 'assets:precompile'
|
|
80
|
-
def_option(:precompile_assets_command) { "rake #{precompile_assets_task} RAILS_GROUPS=assets" }
|
|
81
80
|
def_option :asset_strategy, 'shifting'
|
|
82
81
|
def_option :asset_dependencies, %w[app/assets lib/assets vendor/assets Gemfile.lock config/routes.rb config/application.rb]
|
|
83
82
|
def_option :asset_roles, [:app_master, :app, :solo]
|
|
@@ -272,6 +272,7 @@ chmod 0700 #{path}
|
|
|
272
272
|
|
|
273
273
|
# task
|
|
274
274
|
def copy_repository_cache
|
|
275
|
+
paths.new_release!
|
|
275
276
|
shell.status "Copying to #{paths.active_release}"
|
|
276
277
|
exclusions = Array(config.copy_exclude).map { |e| %|--exclude="#{e}"| }.join(' ')
|
|
277
278
|
run("mkdir -p #{paths.active_release} #{paths.shared_config} && rsync -aq #{exclusions} #{paths.repository_cache}/ #{paths.active_release}")
|
|
@@ -352,8 +353,8 @@ YML
|
|
|
352
353
|
[
|
|
353
354
|
["Set group write permissions", "chmod -R g+w #{paths.active_release}"],
|
|
354
355
|
["Remove public/system if symlinked", "if [ -L \"#{paths.public_system}\" ]; then rm -rf #{paths.public_system}; fi"],
|
|
355
|
-
["Remove symlinked shared directories", "rm -rf #{paths.active_log} #{paths.active_release}/tmp"],
|
|
356
|
-
["Create tmp directory", "mkdir -p #{paths.
|
|
356
|
+
["Remove symlinked shared directories", "rm -rf #{paths.active_log} #{paths.active_release}/tmp/pids"],
|
|
357
|
+
["Create tmp directory", "mkdir -p #{paths.active_release}/tmp"],
|
|
357
358
|
["Create public directory", "mkdir -p #{paths.public}"],
|
|
358
359
|
["Create config directory", "mkdir -p #{paths.active_release_config}"],
|
|
359
360
|
["Symlink shared log directory", "ln -nfs #{paths.shared_log} #{paths.active_log}"],
|
|
@@ -2,6 +2,8 @@ module EY
|
|
|
2
2
|
module Serverside
|
|
3
3
|
class Maintenance
|
|
4
4
|
|
|
5
|
+
attr_reader :config, :shell
|
|
6
|
+
|
|
5
7
|
def initialize(servers, config, shell)
|
|
6
8
|
@servers, @config, @shell = servers, config, shell
|
|
7
9
|
end
|
|
@@ -14,6 +16,15 @@ module EY
|
|
|
14
16
|
@up
|
|
15
17
|
end
|
|
16
18
|
|
|
19
|
+
def status
|
|
20
|
+
if exist?
|
|
21
|
+
shell.info "Maintenance page: up"
|
|
22
|
+
else
|
|
23
|
+
shell.info "Maintenance page: down"
|
|
24
|
+
end
|
|
25
|
+
exist?
|
|
26
|
+
end
|
|
27
|
+
|
|
17
28
|
def manually_enable
|
|
18
29
|
if paths.deployed?
|
|
19
30
|
enable
|
|
@@ -50,8 +61,6 @@ module EY
|
|
|
50
61
|
|
|
51
62
|
protected
|
|
52
63
|
|
|
53
|
-
attr_reader :config, :shell
|
|
54
|
-
|
|
55
64
|
def using_maintenance_page?
|
|
56
65
|
config.maintenance_on_restart? || (config.migrate? && config.maintenance_on_migrate?)
|
|
57
66
|
end
|
|
@@ -109,7 +118,7 @@ This application stack does not support no-downtime restarts.
|
|
|
109
118
|
end
|
|
110
119
|
|
|
111
120
|
def public_system_symlink_warning
|
|
112
|
-
if paths.
|
|
121
|
+
if paths.active_release.join('public','system').realpath != maintenance_page_dirname.realpath
|
|
113
122
|
shell.warning <<-WARN
|
|
114
123
|
Current repository layout does not allow for maintenance pages!
|
|
115
124
|
Web traffic may still be served to your application.
|
|
@@ -96,6 +96,19 @@ module EY
|
|
|
96
96
|
@deploy_root = Pathname.new(@opts[:deploy_root] || "/data/#{@app_name}")
|
|
97
97
|
end
|
|
98
98
|
|
|
99
|
+
def release_dirname
|
|
100
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def new_release!
|
|
104
|
+
@active_release = path(:releases, release_dirname)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# If no active release is defined, use current
|
|
108
|
+
def active_release
|
|
109
|
+
@active_release || latest_release
|
|
110
|
+
end
|
|
111
|
+
|
|
99
112
|
def deploy_key
|
|
100
113
|
path(:home, '.ssh', "#{@app_name}-deploy-key")
|
|
101
114
|
end
|
|
@@ -116,10 +129,6 @@ module EY
|
|
|
116
129
|
@repository_cache ||= default_repository_cache
|
|
117
130
|
end
|
|
118
131
|
|
|
119
|
-
def active_release
|
|
120
|
-
@active_release ||= path(:releases, Time.now.utc.strftime("%Y%m%d%H%M%S"))
|
|
121
|
-
end
|
|
122
|
-
|
|
123
132
|
def all_releases
|
|
124
133
|
@all_releases ||= Pathname.glob(releases.join('*')).sort
|
|
125
134
|
end
|
|
@@ -19,8 +19,7 @@ module EY
|
|
|
19
19
|
def_delegators :config,
|
|
20
20
|
:paths, :asset_dependencies, :asset_roles,
|
|
21
21
|
:framework_envs, :precompile_assets?, :skip_precompile_assets?,
|
|
22
|
-
:precompile_unchanged_assets?, :precompile_assets_task
|
|
23
|
-
:precompile_assets_command
|
|
22
|
+
:precompile_unchanged_assets?, :precompile_assets_task
|
|
24
23
|
|
|
25
24
|
def detect_and_compile
|
|
26
25
|
runner.roles asset_roles do
|
|
@@ -53,15 +52,8 @@ module EY
|
|
|
53
52
|
def run_precompile_assets_task
|
|
54
53
|
asset_strategy.prepare do
|
|
55
54
|
cd = "cd #{paths.active_release}"
|
|
56
|
-
task = "PATH=#{paths.binstubs}:$PATH #{framework_envs} #{
|
|
57
|
-
|
|
58
|
-
shell.status "Compiling assets once"
|
|
59
|
-
system("sh -l -c '#{cd} && #{task}'")
|
|
60
|
-
|
|
61
|
-
shell.status "Syncing assets to remote servers"
|
|
62
|
-
runner.servers.remote.run_for_each do |server|
|
|
63
|
-
server.sync_directory_command(paths.public_assets)
|
|
64
|
-
end
|
|
55
|
+
task = "PATH=#{paths.binstubs}:$PATH #{framework_envs} rake #{precompile_assets_task} RAILS_GROUPS=assets"
|
|
56
|
+
runner.run "#{cd} && #{task}"
|
|
65
57
|
end
|
|
66
58
|
end
|
|
67
59
|
|
data/spec/archive_deploy_spec.rb
CHANGED
data/spec/custom_deploy_spec.rb
CHANGED
|
@@ -3,50 +3,37 @@ require 'spec_helper'
|
|
|
3
3
|
describe "the EY::Serverside::Deploy API" do
|
|
4
4
|
it "calls tasks in the right order" do
|
|
5
5
|
class TestDeploy < FullTestDeploy
|
|
6
|
-
# This happens before require_custom_tasks, so it's not
|
|
7
|
-
# overrideable. That's why it's not in @call_order.
|
|
8
|
-
def update_repository_cache() end
|
|
9
|
-
def check_repository() end
|
|
10
|
-
|
|
11
|
-
# cheat a bit; we don't actually want to do these things
|
|
12
|
-
def require_custom_tasks() end
|
|
13
|
-
def callback(*_) end
|
|
14
|
-
|
|
15
6
|
attr_reader :call_order
|
|
16
7
|
def initialize(*a)
|
|
17
8
|
super
|
|
18
9
|
@call_order = []
|
|
19
10
|
end
|
|
20
11
|
|
|
21
|
-
def
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def
|
|
28
|
-
def
|
|
29
|
-
def
|
|
30
|
-
def
|
|
31
|
-
def
|
|
32
|
-
def
|
|
33
|
-
def
|
|
34
|
-
def
|
|
35
|
-
def symlink() @call_order << 'symlink' end
|
|
36
|
-
def restart() @call_order << 'restart' end
|
|
37
|
-
def cleanup_old_releases() @call_order << 'cleanup_old_releases' end
|
|
38
|
-
def enable_maintenance_page() @call_order << 'enable_maintenance_page' end
|
|
39
|
-
def disable_maintenance_page() @call_order << 'disable_maintenance_page' end
|
|
40
|
-
def gc_repository_cache() @call_order << 'gc_repository_cache' end
|
|
12
|
+
def push_code() @call_order << 'push_code' ; super end
|
|
13
|
+
def copy_repository_cache() @call_order << 'copy_repository_cache' ; super end
|
|
14
|
+
def create_revision_file() @call_order << 'create_revision_file' ; super end
|
|
15
|
+
def bundle() @call_order << 'bundle' ; super end
|
|
16
|
+
def setup_services() @call_order << 'setup_services' ; super end
|
|
17
|
+
def symlink_configs() @call_order << 'symlink_configs' ; super end
|
|
18
|
+
def migrate() @call_order << 'migrate' ; super end
|
|
19
|
+
def compile_assets() @call_order << 'compile_assets' ; super end
|
|
20
|
+
def symlink() @call_order << 'symlink' ; super end
|
|
21
|
+
def restart() @call_order << 'restart' ; super end
|
|
22
|
+
def cleanup_old_releases() @call_order << 'cleanup_old_releases' ; super end
|
|
23
|
+
def enable_maintenance_page() @call_order << 'enable_maintenance_page' ; super end
|
|
24
|
+
def disable_maintenance_page() @call_order << 'disable_maintenance_page'; super end
|
|
25
|
+
def gc_repository_cache() @call_order << 'gc_repository_cache' ; super end
|
|
41
26
|
end
|
|
42
27
|
|
|
43
|
-
config = EY::Serverside::Deploy::Configuration.new(
|
|
44
|
-
'app' => 'app_name',
|
|
45
|
-
'framework_env' => 'staging',
|
|
46
|
-
})
|
|
28
|
+
config = EY::Serverside::Deploy::Configuration.new(default_configuration)
|
|
47
29
|
|
|
48
30
|
td = TestDeploy.realnew(test_servers, config, test_shell)
|
|
49
|
-
|
|
31
|
+
mock_bundler
|
|
32
|
+
with_mocked_commands do
|
|
33
|
+
capture do
|
|
34
|
+
td.deploy
|
|
35
|
+
end
|
|
36
|
+
end
|
|
50
37
|
|
|
51
38
|
############################# IMPORTANT ####################################
|
|
52
39
|
#
|
data/spec/deploy_hook_spec.rb
CHANGED
|
@@ -32,7 +32,7 @@ describe "deploy hooks" do
|
|
|
32
32
|
|
|
33
33
|
it "prints the failure to the log even when non-verbose" do
|
|
34
34
|
out = read_output
|
|
35
|
-
expect(out).to match(%r|FATAL: Exception raised in deploy hook .*/before_deploy.rb.|)
|
|
35
|
+
expect(out).to match(%r|FATAL: Exception raised in deploy hook .*/deploy/before_deploy.rb.|)
|
|
36
36
|
expect(out).to match(%r|RuntimeError:.*Hook failing in \(eval\)|)
|
|
37
37
|
expect(out).to match(%r|Please fix this error before retrying.|)
|
|
38
38
|
end
|
|
@@ -68,13 +68,16 @@ describe "deploy hooks" do
|
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
context "deploy hook API" do
|
|
71
|
-
|
|
72
71
|
def deploy_hook(options={})
|
|
73
72
|
config = EY::Serverside::Deploy::Configuration.new({
|
|
74
73
|
'app' => 'app_name',
|
|
75
74
|
'framework_env' => 'staging',
|
|
76
75
|
'current_roles' => ['solo'],
|
|
76
|
+
'deploy_to' => deploy_dir.to_s,
|
|
77
77
|
}.merge(options))
|
|
78
|
+
# setup to run hooks since a deploy hasn't happened
|
|
79
|
+
config.paths.new_release!
|
|
80
|
+
config.paths.active_release.mkpath
|
|
78
81
|
EY::Serverside::DeployHook.new(config, test_shell, 'fake_test_hook')
|
|
79
82
|
end
|
|
80
83
|
|
|
@@ -102,7 +105,7 @@ describe "deploy hooks" do
|
|
|
102
105
|
deploy_hook.eval_hook('run!("false")')
|
|
103
106
|
}.to raise_error(RuntimeError)
|
|
104
107
|
out = read_output
|
|
105
|
-
expect(out).to match(%r|FATAL: Exception raised in deploy hook
|
|
108
|
+
expect(out).to match(%r|FATAL: Exception raised in deploy hook .*/deploy/fake_test_hook.rb.|)
|
|
106
109
|
expect(out).to match(%r|RuntimeError: .*run!.*Command failed. false|)
|
|
107
110
|
expect(out).to match(%r|Please fix this error before retrying.|)
|
|
108
111
|
end
|
|
@@ -128,7 +131,7 @@ describe "deploy hooks" do
|
|
|
128
131
|
}.to raise_error(RuntimeError)
|
|
129
132
|
end
|
|
130
133
|
out = read_output
|
|
131
|
-
expect(out).to match(%r|FATAL: Exception raised in deploy hook
|
|
134
|
+
expect(out).to match(%r|FATAL: Exception raised in deploy hook .*/deploy/fake_test_hook.rb.|)
|
|
132
135
|
expect(out).to match(%r|RuntimeError: .*sudo!.*Command failed. false|)
|
|
133
136
|
expect(out).to match(%r|Please fix this error before retrying.|)
|
|
134
137
|
end
|
|
@@ -150,7 +153,7 @@ describe "deploy hooks" do
|
|
|
150
153
|
expect(deploy_hook.eval_hook('shared_path.nil?')).to be_false
|
|
151
154
|
out = read_output
|
|
152
155
|
expect(out).to include("Use of `shared_path` (via method_missing) is deprecated in favor of `config.shared_path` for improved error messages and compatibility.")
|
|
153
|
-
expect(out).to match(%r|in
|
|
156
|
+
expect(out).to match(%r|in .*/deploy/fake_test_hook.rb|)
|
|
154
157
|
end
|
|
155
158
|
end
|
|
156
159
|
|
|
@@ -190,7 +193,7 @@ describe "deploy hooks" do
|
|
|
190
193
|
out = read_output
|
|
191
194
|
expect(out).to match(%r|Use of `@node` in deploy hooks is deprecated.|)
|
|
192
195
|
expect(out).to match(%r|Please use `config.node`, which provides access to the same object.|)
|
|
193
|
-
expect(out).to match(%r
|
|
196
|
+
expect(out).to match(%r|.*/deploy/fake_test_hook.rb|)
|
|
194
197
|
end
|
|
195
198
|
|
|
196
199
|
it "is available" do
|
|
@@ -219,7 +222,7 @@ describe "deploy hooks" do
|
|
|
219
222
|
out = read_output
|
|
220
223
|
expect(out).to match(%r|Use of `@configuration` in deploy hooks is deprecated.|)
|
|
221
224
|
expect(out).to match(%r|Please use `config`, which provides access to the same object.|)
|
|
222
|
-
expect(out).to match(%r
|
|
225
|
+
expect(out).to match(%r|.*/deploy/fake_test_hook.rb|)
|
|
223
226
|
end
|
|
224
227
|
|
|
225
228
|
it "has the configuration in it" do
|
|
@@ -336,7 +339,7 @@ describe "deploy hooks" do
|
|
|
336
339
|
deploy_hook.eval_hook('methedo_no_existo')
|
|
337
340
|
}.to raise_error(NameError)
|
|
338
341
|
out = read_output
|
|
339
|
-
expect(out).to match(%r|FATAL: Exception raised in deploy hook
|
|
342
|
+
expect(out).to match(%r|FATAL: Exception raised in deploy hook .*/deploy/fake_test_hook.rb.|)
|
|
340
343
|
expect(out).to match(%r|NameError: undefined local variable or method `methedo_no_existo' for|)
|
|
341
344
|
expect(out).to match(%r|Please fix this error before retrying.|)
|
|
342
345
|
end
|
data/spec/git_strategy_spec.rb
CHANGED
|
@@ -8,7 +8,7 @@ end
|
|
|
8
8
|
|
|
9
9
|
describe EY::Serverside::Source::Git do
|
|
10
10
|
before do
|
|
11
|
-
@source_cache = tmpdir.join("gitrepo-#{Time.now.utc.strftime("%Y%m%d%H%M%S")}
|
|
11
|
+
@source_cache = tmpdir.join("gitrepo-#{Time.now.utc.strftime("%Y%m%d%H%M%S")}-#{$$}")
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe EY::Serverside::Maintenance do
|
|
4
|
+
let(:maintenance_path) { deploy_dir.join('shared', 'system', 'maintenance.html') }
|
|
5
|
+
|
|
6
|
+
context "deployed application" do
|
|
7
|
+
before do
|
|
8
|
+
deploy_test_application
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "enables the maintenance page" do
|
|
12
|
+
enable_maintenance
|
|
13
|
+
expect(maintenance_path).to exist
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "disables an enabled maintenance page" do
|
|
17
|
+
enable_maintenance
|
|
18
|
+
expect(maintenance_path).to exist
|
|
19
|
+
disable_maintenance
|
|
20
|
+
expect(maintenance_path).to_not exist
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "lets you know if the app is in maintenance mode" do
|
|
24
|
+
maintenance_status
|
|
25
|
+
maintenance_output = read_output.split("\n").select{|l| l.match("Maintenance")}
|
|
26
|
+
maintenance_output.count.should == 1
|
|
27
|
+
maintenance_output.first.should match(/Maintenance page: down$/)
|
|
28
|
+
|
|
29
|
+
enable_maintenance
|
|
30
|
+
|
|
31
|
+
maintenance_status
|
|
32
|
+
maintenance_output = read_output.split("\n").select{|l| l.match("Maintenance")}
|
|
33
|
+
maintenance_output.count.should == 1
|
|
34
|
+
maintenance_output.first.should match(/Maintenance page: up$/)
|
|
35
|
+
|
|
36
|
+
disable_maintenance
|
|
37
|
+
|
|
38
|
+
maintenance_status
|
|
39
|
+
maintenance_output = read_output.split("\n").select{|l| l.match("Maintenance")}
|
|
40
|
+
maintenance_output.count.should == 1
|
|
41
|
+
maintenance_output.first.should match(/Maintenance page: down$/)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -17,6 +17,7 @@ require 'engineyard-serverside'
|
|
|
17
17
|
require 'engineyard-serverside-adapter'
|
|
18
18
|
require 'support/integration'
|
|
19
19
|
require 'support/source_doubles'
|
|
20
|
+
require 'support/timecop'
|
|
20
21
|
|
|
21
22
|
FIXTURES_DIR = Pathname.new(__FILE__).dirname.join("fixtures")
|
|
22
23
|
TMPDIR = Pathname.new(__FILE__).dirname.parent.join('tmp')
|
|
@@ -210,27 +211,19 @@ exec "$@"
|
|
|
210
211
|
@deploy_dir ||= tmpdir.join("serverside-deploy-#{Time.now.to_f}-#{$$}")
|
|
211
212
|
end
|
|
212
213
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
# is very very low.
|
|
216
|
-
#
|
|
217
|
-
# can't use %L n strftime because old ruby doesn't support it.
|
|
218
|
-
def release_path
|
|
219
|
-
deploy_dir.join('releases', Time.now.utc.strftime("%Y%m%d%H%M%S#{Time.now.tv_usec}"))
|
|
214
|
+
def whoami
|
|
215
|
+
ENV['USER']
|
|
220
216
|
end
|
|
221
217
|
|
|
222
218
|
# set up EY::Serverside::Server like we're on a solo
|
|
223
219
|
def test_servers
|
|
224
|
-
@test_servers ||= EY::Serverside::Servers.from_hashes([{:hostname => 'localhost', :roles => %w[solo], :user =>
|
|
220
|
+
@test_servers ||= EY::Serverside::Servers.from_hashes([{:hostname => 'localhost', :roles => %w[solo], :user => whoami}], test_shell)
|
|
225
221
|
end
|
|
226
222
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
def deploy_test_application(repo_fixture_name = 'default', extra_config = {}, &block)
|
|
230
|
-
options = {
|
|
223
|
+
def default_configuration
|
|
224
|
+
{
|
|
231
225
|
"source_class" => "IntegrationSpec",
|
|
232
226
|
"deploy_to" => deploy_dir.to_s,
|
|
233
|
-
"release_path" => release_path.to_s,
|
|
234
227
|
"group" => GROUP,
|
|
235
228
|
"stack" => 'nginx_passenger',
|
|
236
229
|
"migrate" => "ruby -e 'puts ENV[\"PATH\"]' > #{deploy_dir}/path-when-migrating",
|
|
@@ -240,8 +233,12 @@ exec "$@"
|
|
|
240
233
|
"framework_env" => 'staging',
|
|
241
234
|
"branch" => 'somebranch',
|
|
242
235
|
"verbose" => true,
|
|
243
|
-
"git" => FIXTURES_DIR.join('repos',
|
|
244
|
-
}
|
|
236
|
+
"git" => FIXTURES_DIR.join('repos', 'default'),
|
|
237
|
+
}
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def test_adapter(repo_fixture_name = 'default', extra_config = {})
|
|
241
|
+
options = default_configuration.merge({ "git" => FIXTURES_DIR.join('repos', repo_fixture_name)}).merge(extra_config)
|
|
245
242
|
|
|
246
243
|
# pretend there is a shared bundled_gems directory
|
|
247
244
|
deploy_dir.join('shared', 'bundled_gems').mkpath
|
|
@@ -249,8 +246,7 @@ exec "$@"
|
|
|
249
246
|
deploy_dir.join('shared', 'bundled_gems', name).open("w") { |f| f.write("old\n") }
|
|
250
247
|
end
|
|
251
248
|
|
|
252
|
-
|
|
253
|
-
@adapter = EY::Serverside::Adapter.new do |args|
|
|
249
|
+
EY::Serverside::Adapter.new do |args|
|
|
254
250
|
args.app = options['app']
|
|
255
251
|
args.environment_name = options['environment_name']
|
|
256
252
|
args.account_name = options['account_name']
|
|
@@ -263,8 +259,7 @@ exec "$@"
|
|
|
263
259
|
"services_setup_command" => "echo 'services setup command'",
|
|
264
260
|
"source_class" => options["source_class"],
|
|
265
261
|
"deploy_to" => options["deploy_to"],
|
|
266
|
-
"
|
|
267
|
-
"group" => options["group"]
|
|
262
|
+
"group" => options["group"],
|
|
268
263
|
}.merge(options['config'] || {})
|
|
269
264
|
args.framework_env = options['framework_env']
|
|
270
265
|
args.stack = options['stack']
|
|
@@ -272,12 +267,18 @@ exec "$@"
|
|
|
272
267
|
args.clean = options['clean']
|
|
273
268
|
args.instances = test_servers.map {|s| {:hostname => s.hostname, :roles => s.roles.to_a, :name => s.name} }
|
|
274
269
|
end
|
|
270
|
+
end
|
|
275
271
|
|
|
272
|
+
# When a repo fixture name is specified, the files found in the specified
|
|
273
|
+
# spec/fixtures/repos dir are copied into the test github repository.
|
|
274
|
+
def deploy_test_application(repo_fixture_name = 'default', extra_config = {}, &block)
|
|
275
|
+
Timecop.travel(1)
|
|
276
|
+
@adapter = test_adapter(repo_fixture_name, extra_config)
|
|
276
277
|
@argv = @adapter.deploy.commands.last.to_argv[2..-1]
|
|
277
278
|
|
|
278
279
|
FullTestDeploy.on_create_callback = block
|
|
279
280
|
|
|
280
|
-
mock_bundler(
|
|
281
|
+
mock_bundler(extra_config['bundle_install_fails'])
|
|
281
282
|
with_mocked_commands do
|
|
282
283
|
capture do
|
|
283
284
|
EY::Serverside::CLI.start(@argv)
|
|
@@ -289,13 +290,11 @@ exec "$@"
|
|
|
289
290
|
end
|
|
290
291
|
|
|
291
292
|
def redeploy_test_application(extra_config = {}, &block)
|
|
293
|
+
Timecop.travel(1)
|
|
292
294
|
raise "Please deploy_test_application first" unless @argv
|
|
293
295
|
bundle_install_fails = extra_config.delete('bundle_install_fails')
|
|
294
296
|
|
|
295
297
|
@action = @adapter.deploy do |args|
|
|
296
|
-
# we must refresh the release path every deploy since we're setting it manually
|
|
297
|
-
args.config = args.config.merge({'release_path' => release_path})
|
|
298
|
-
|
|
299
298
|
extra_config.each do |key,val|
|
|
300
299
|
case key
|
|
301
300
|
when 'branch' then args.ref = val
|
|
@@ -320,4 +319,37 @@ exec "$@"
|
|
|
320
319
|
@deployer = EY::Serverside::Deploy.deployer
|
|
321
320
|
@config = EY::Serverside::Deploy.config
|
|
322
321
|
end
|
|
322
|
+
|
|
323
|
+
def enable_maintenance(extra_adapter_config = {})
|
|
324
|
+
@adapter = test_adapter("default", extra_adapter_config)
|
|
325
|
+
@argv = @adapter.enable_maintenance.commands.last.to_argv[2..-1]
|
|
326
|
+
|
|
327
|
+
with_mocked_commands do
|
|
328
|
+
capture do
|
|
329
|
+
EY::Serverside::CLI.start(@argv)
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
def disable_maintenance(extra_adapter_config = {})
|
|
335
|
+
@adapter = test_adapter("default", extra_adapter_config)
|
|
336
|
+
@argv = @adapter.disable_maintenance.commands.last.to_argv[2..-1]
|
|
337
|
+
|
|
338
|
+
with_mocked_commands do
|
|
339
|
+
capture do
|
|
340
|
+
EY::Serverside::CLI.start(@argv)
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
def maintenance_status(extra_adapter_config = {})
|
|
346
|
+
@adapter = test_adapter("default", extra_adapter_config)
|
|
347
|
+
@argv = @adapter.maintenance_status.commands.last.to_argv[2..-1]
|
|
348
|
+
|
|
349
|
+
with_mocked_commands do
|
|
350
|
+
capture do
|
|
351
|
+
EY::Serverside::CLI.start(@argv)
|
|
352
|
+
end
|
|
353
|
+
end
|
|
354
|
+
end
|
|
323
355
|
end
|
metadata
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: engineyard-serverside
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.5.0
|
|
5
|
-
prerelease:
|
|
4
|
+
version: 2.5.0
|
|
5
|
+
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
8
8
|
- EY Cloud Team
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2014-09-
|
|
12
|
+
date: 2014-09-23 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: rspec
|
|
@@ -114,7 +114,7 @@ dependencies:
|
|
|
114
114
|
requirements:
|
|
115
115
|
- - ~>
|
|
116
116
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: 2.
|
|
117
|
+
version: 2.4.0
|
|
118
118
|
type: :development
|
|
119
119
|
prerelease: false
|
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -122,7 +122,7 @@ dependencies:
|
|
|
122
122
|
requirements:
|
|
123
123
|
- - ~>
|
|
124
124
|
- !ruby/object:Gem::Version
|
|
125
|
-
version: 2.
|
|
125
|
+
version: 2.4.0
|
|
126
126
|
- !ruby/object:Gem::Dependency
|
|
127
127
|
name: sqlite3
|
|
128
128
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -447,6 +447,7 @@ files:
|
|
|
447
447
|
- spec/fixtures/valid_hook.rb
|
|
448
448
|
- spec/git_strategy_spec.rb
|
|
449
449
|
- spec/lockfile_parser_spec.rb
|
|
450
|
+
- spec/maintenance_spec.rb
|
|
450
451
|
- spec/multi_dependency_manager_spec.rb
|
|
451
452
|
- spec/nodejs_deploy_spec.rb
|
|
452
453
|
- spec/php_deploy_spec.rb
|
|
@@ -462,6 +463,7 @@ files:
|
|
|
462
463
|
- spec/sqlite3_deploy_spec.rb
|
|
463
464
|
- spec/support/integration.rb
|
|
464
465
|
- spec/support/source_doubles.rb
|
|
466
|
+
- spec/support/timecop.rb
|
|
465
467
|
- spec/symlink_spec.rb
|
|
466
468
|
homepage: http://github.com/engineyard/engineyard-serverside
|
|
467
469
|
licenses:
|
|
@@ -476,6 +478,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
476
478
|
- - ! '>='
|
|
477
479
|
- !ruby/object:Gem::Version
|
|
478
480
|
version: '0'
|
|
481
|
+
segments:
|
|
482
|
+
- 0
|
|
483
|
+
hash: 1515425711168251653
|
|
479
484
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
480
485
|
none: false
|
|
481
486
|
requirements:
|
|
@@ -654,6 +659,7 @@ test_files:
|
|
|
654
659
|
- spec/fixtures/valid_hook.rb
|
|
655
660
|
- spec/git_strategy_spec.rb
|
|
656
661
|
- spec/lockfile_parser_spec.rb
|
|
662
|
+
- spec/maintenance_spec.rb
|
|
657
663
|
- spec/multi_dependency_manager_spec.rb
|
|
658
664
|
- spec/nodejs_deploy_spec.rb
|
|
659
665
|
- spec/php_deploy_spec.rb
|
|
@@ -669,4 +675,5 @@ test_files:
|
|
|
669
675
|
- spec/sqlite3_deploy_spec.rb
|
|
670
676
|
- spec/support/integration.rb
|
|
671
677
|
- spec/support/source_doubles.rb
|
|
678
|
+
- spec/support/timecop.rb
|
|
672
679
|
- spec/symlink_spec.rb
|