engineyard-serverside 1.5.10 → 1.5.12
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/engineyard-serverside/configuration.rb +4 -0
- data/lib/engineyard-serverside/deploy.rb +27 -1
- data/lib/engineyard-serverside/lockfile_parser.rb +1 -1
- data/lib/engineyard-serverside/version.rb +1 -1
- data/spec/basic_deploy_spec.rb +29 -14
- data/spec/bundler_deploy_spec.rb +1 -1
- data/spec/fixtures/gitrepo/bar +0 -0
- data/spec/lockfile_parser_spec.rb +1 -1
- data/spec/services_deploy_spec.rb +131 -0
- data/spec/support/integration.rb +34 -13
- metadata +44 -13
@@ -4,6 +4,13 @@ require 'fileutils'
|
|
4
4
|
require 'json'
|
5
5
|
require 'engineyard-serverside/rails_asset_support'
|
6
6
|
|
7
|
+
begin
|
8
|
+
require 'ey_instance_api_client'
|
9
|
+
rescue LoadError
|
10
|
+
puts "Using Ruby #{RUBY_VERSION}"
|
11
|
+
# engineyard-serverside SOMETIMES runs under the system ruby instead of resin ruby
|
12
|
+
end
|
13
|
+
|
7
14
|
module EY
|
8
15
|
module Serverside
|
9
16
|
class DeployBase < Task
|
@@ -29,6 +36,7 @@ module EY
|
|
29
36
|
with_failed_release_cleanup do
|
30
37
|
create_revision_file
|
31
38
|
run_with_callbacks(:bundle)
|
39
|
+
fetch_configs
|
32
40
|
symlink_configs
|
33
41
|
conditionally_enable_maintenance_page
|
34
42
|
run_with_callbacks(:migrate)
|
@@ -259,6 +267,24 @@ WRAP
|
|
259
267
|
run create_revision_file_command
|
260
268
|
end
|
261
269
|
|
270
|
+
def services_fetcher
|
271
|
+
EY::InstanceAPIClient::Services.new
|
272
|
+
end
|
273
|
+
|
274
|
+
def fetch_configs
|
275
|
+
info "~> Fetching configuration resources."
|
276
|
+
services_data = services_fetcher.get(config.app)
|
277
|
+
File.open("#{c.shared_path}/config/ey_services_config_deploy.yml", "w") do |f|
|
278
|
+
YAML.dump(services_data, f)
|
279
|
+
end
|
280
|
+
rescue StandardError => e
|
281
|
+
warning <<-WARNING
|
282
|
+
External services configuration not updated. Using previous version.
|
283
|
+
Deploy again if your services configuration appears incomplete or out of date.
|
284
|
+
#{e}
|
285
|
+
WARNING
|
286
|
+
end
|
287
|
+
|
262
288
|
def symlink_configs(release_to_link=c.release_path)
|
263
289
|
info "~> Preparing shared resources for release."
|
264
290
|
symlink_tasks(release_to_link).each do |what, cmd|
|
@@ -320,7 +346,7 @@ WRAP
|
|
320
346
|
|
321
347
|
def base_callback_command_for(what)
|
322
348
|
[serverside_bin, 'hook', what.to_s,
|
323
|
-
'--app', config.app
|
349
|
+
'--app', config.app,
|
324
350
|
'--release-path', config.release_path.to_s,
|
325
351
|
'--framework-env', c.environment.to_s,
|
326
352
|
].compact
|
data/spec/basic_deploy_spec.rb
CHANGED
@@ -4,7 +4,7 @@ describe "Deploying an application without Bundler" do
|
|
4
4
|
before(:all) do
|
5
5
|
$DISABLE_GEMFILE = true # Don't generate Gemfile/Gemfile.lock
|
6
6
|
$DISABLE_LOCKFILE = true
|
7
|
-
@deploy_dir =
|
7
|
+
@deploy_dir = Pathname.new(Dir.tmpdir).join("serverside-deploy-#{Time.now.to_i}-#{$$}")
|
8
8
|
|
9
9
|
# set up EY::Serverside::Server like we're on a solo
|
10
10
|
EY::Serverside::Server.reset
|
@@ -13,7 +13,7 @@ describe "Deploying an application without Bundler" do
|
|
13
13
|
# run a deploy
|
14
14
|
config = EY::Serverside::Deploy::Configuration.new({
|
15
15
|
"strategy" => "IntegrationSpec",
|
16
|
-
"deploy_to" => @deploy_dir,
|
16
|
+
"deploy_to" => @deploy_dir.to_s,
|
17
17
|
"group" => `id -gn`.strip,
|
18
18
|
"stack" => 'nginx_passenger',
|
19
19
|
"migrate" => nil,
|
@@ -26,24 +26,39 @@ describe "Deploying an application without Bundler" do
|
|
26
26
|
@deployer.deploy
|
27
27
|
end
|
28
28
|
|
29
|
+
def exist
|
30
|
+
be_exist
|
31
|
+
end
|
32
|
+
|
29
33
|
it "creates a REVISION file" do
|
30
|
-
|
34
|
+
@deploy_dir.join('current', 'REVISION').should exist
|
31
35
|
end
|
32
36
|
|
33
37
|
it "restarts the app servers" do
|
34
|
-
|
38
|
+
@deploy_dir.join('current', 'restart').should exist
|
35
39
|
end
|
36
40
|
|
37
41
|
it "runs all the hooks" do
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
42
|
+
@deploy_dir.join('current', 'before_bundle.ran' ).should exist
|
43
|
+
@deploy_dir.join('current', 'after_bundle.ran' ).should exist
|
44
|
+
@deploy_dir.join('current', 'before_migrate.ran').should exist
|
45
|
+
@deploy_dir.join('current', 'after_migrate.ran' ).should exist
|
46
|
+
@deploy_dir.join('current', 'before_compile_assets.ran').should exist
|
47
|
+
@deploy_dir.join('current', 'after_compile_assets.ran' ).should exist
|
48
|
+
@deploy_dir.join('current', 'before_symlink.ran').should exist
|
49
|
+
@deploy_dir.join('current', 'after_symlink.ran' ).should exist
|
50
|
+
@deploy_dir.join('current', 'before_restart.ran').should exist
|
51
|
+
@deploy_dir.join('current', 'after_restart.ran' ).should exist
|
52
|
+
end
|
53
|
+
|
54
|
+
it "creates and symlinks ey_services_config_deploy.yml" do
|
55
|
+
shared_services_file = @deploy_dir.join('shared', 'config', 'ey_services_config_deploy.yml')
|
56
|
+
symlinked_services_file = @deploy_dir.join('current', 'config', 'ey_services_config_deploy.yml')
|
57
|
+
|
58
|
+
shared_services_file.should exist
|
59
|
+
shared_services_file.should_not be_symlink
|
60
|
+
|
61
|
+
symlinked_services_file.should exist
|
62
|
+
symlinked_services_file.should be_symlink
|
48
63
|
end
|
49
64
|
end
|
data/spec/bundler_deploy_spec.rb
CHANGED
@@ -96,7 +96,7 @@ describe "Deploying an application that uses Bundler" do
|
|
96
96
|
end
|
97
97
|
|
98
98
|
it "installs the proper Bundler version" do
|
99
|
-
@bundler_version.should == "1.0.
|
99
|
+
@bundler_version.should == "1.0.21" # Something should break when the default changes.
|
100
100
|
install_bundler_command_ran = @deployer.commands.detect{ |command| command.index("install_bundler") }
|
101
101
|
install_bundler_command_ran.should_not be_nil
|
102
102
|
install_bundler_command_ran.should include("#{@binpath} install_bundler #{@bundler_version}")
|
File without changes
|
@@ -80,7 +80,7 @@ describe "the bundler version retrieved from the lockfile" do
|
|
80
80
|
end
|
81
81
|
|
82
82
|
it "uses the default version when we get a pessimistic qualifier and is lower than the default version" do
|
83
|
-
subject.fetch_version('1.0.1', '~>').should == '1.0.
|
83
|
+
subject.fetch_version('1.0.1', '~>').should == '1.0.21'
|
84
84
|
end
|
85
85
|
|
86
86
|
it "uses the given version when we get a pessimistic qualifier that doesn't match the default version" do
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Deploying an application with services" do
|
4
|
+
before(:each) do
|
5
|
+
#$DISABLE_GEMFILE = true # Don't generate Gemfile/Gemfile.lock
|
6
|
+
#$DISABLE_LOCKFILE = true
|
7
|
+
@deploy_dir = Pathname.new(Dir.tmpdir).join("serverside-deploy-#{Time.now.to_i}-#{$$}")
|
8
|
+
|
9
|
+
# set up EY::Serverside::Server like we're on a solo
|
10
|
+
EY::Serverside::Server.reset
|
11
|
+
EY::Serverside::Server.add(:hostname => 'localhost', :roles => %w[solo])
|
12
|
+
end
|
13
|
+
|
14
|
+
def setup_deploy
|
15
|
+
# run a deploy
|
16
|
+
config = EY::Serverside::Deploy::Configuration.new({
|
17
|
+
"strategy" => "IntegrationSpec",
|
18
|
+
"deploy_to" => @deploy_dir.to_s,
|
19
|
+
"group" => `id -gn`.strip,
|
20
|
+
"stack" => 'nginx_passenger',
|
21
|
+
"migrate" => nil,
|
22
|
+
'app' => 'foo',
|
23
|
+
'framework_env' => 'staging'
|
24
|
+
})
|
25
|
+
|
26
|
+
EY::Serverside::LoggedOutput.verbose = true
|
27
|
+
@binpath = File.expand_path(File.join(File.dirname(__FILE__), '..', 'bin', 'engineyard-serverside'))
|
28
|
+
FullTestDeploy.new(config)
|
29
|
+
end
|
30
|
+
|
31
|
+
def exist
|
32
|
+
be_exist
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "a succesful deploy" do
|
36
|
+
before do
|
37
|
+
@shared_services_file = @deploy_dir.join('shared', 'config', 'ey_services_config_deploy.yml')
|
38
|
+
@symlinked_services_file = @deploy_dir.join('current', 'config', 'ey_services_config_deploy.yml')
|
39
|
+
|
40
|
+
@deployer = setup_deploy
|
41
|
+
@deployer.set_services_fetcher_value({"a_service" => {"b_key" => "c_value"}})
|
42
|
+
@deployer.deploy
|
43
|
+
end
|
44
|
+
|
45
|
+
it "creates and symlinks ey_services_config_deploy.yml" do
|
46
|
+
@shared_services_file.should exist
|
47
|
+
@shared_services_file.should_not be_symlink
|
48
|
+
@shared_services_file.read.should == YAML.dump({"a_service" => {"b_key" => "c_value"}})
|
49
|
+
|
50
|
+
@symlinked_services_file.should exist
|
51
|
+
@symlinked_services_file.should be_symlink
|
52
|
+
@shared_services_file.read.should == YAML.dump({"a_service" => {"b_key" => "c_value"}})
|
53
|
+
|
54
|
+
@deployer.infos.should_not be_any { |info| info =~ /WARNING/ }
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "followed by a deploy that fails to fetch services" do
|
58
|
+
before do
|
59
|
+
@deployer = setup_deploy
|
60
|
+
@deployer.services_fetcher_breaks!
|
61
|
+
@deployer.deploy
|
62
|
+
end
|
63
|
+
|
64
|
+
it "logs a warning and symlinks the existing config file" do
|
65
|
+
@shared_services_file.should exist
|
66
|
+
@shared_services_file.should_not be_symlink
|
67
|
+
@shared_services_file.read.should == YAML.dump({"a_service" => {"b_key" => "c_value"}})
|
68
|
+
|
69
|
+
@symlinked_services_file.should exist
|
70
|
+
@symlinked_services_file.should be_symlink
|
71
|
+
@shared_services_file.read.should == YAML.dump({"a_service" => {"b_key" => "c_value"}})
|
72
|
+
|
73
|
+
@deployer.infos.should be_any { |info| info =~ /WARNING: External services configuration not updated/ }
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "followed by another successfull deploy" do
|
79
|
+
before do
|
80
|
+
@deployer = setup_deploy
|
81
|
+
@deployer.set_services_fetcher_value({"other_service" => nil})
|
82
|
+
@deployer.deploy
|
83
|
+
end
|
84
|
+
|
85
|
+
it "replaces the config with the new one (and symlinks)" do
|
86
|
+
@shared_services_file.should exist
|
87
|
+
@shared_services_file.should_not be_symlink
|
88
|
+
@shared_services_file.read.should == YAML.dump({"other_service" => nil })
|
89
|
+
|
90
|
+
@symlinked_services_file.should exist
|
91
|
+
@symlinked_services_file.should be_symlink
|
92
|
+
@shared_services_file.read.should == YAML.dump({"other_service" => nil})
|
93
|
+
|
94
|
+
@deployer.infos.should_not be_any { |info| info =~ /WARNING/ }
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
# it "creates and symlinks ey_services_config_deploy.yml" do
|
103
|
+
# shared_services_file = @deploy_dir.join('shared', 'config', 'ey_services_config_deploy.yml')
|
104
|
+
# symlinked_services_file = @deploy_dir.join('current', 'config', 'ey_services_config_deploy.yml')
|
105
|
+
#
|
106
|
+
# @deployer.deploy
|
107
|
+
#
|
108
|
+
# shared_services_file.should exist
|
109
|
+
# shared_services_file.should_not be_symlink
|
110
|
+
#
|
111
|
+
# symlinked_services_file.should exist
|
112
|
+
# symlinked_services_file.should be_symlink
|
113
|
+
# end
|
114
|
+
#
|
115
|
+
# it "prints a warning if it couldn't access the services api" do
|
116
|
+
# @deployer.deploy
|
117
|
+
#
|
118
|
+
# shared_services_file = @deploy_dir.join('shared', 'config', 'ey_services_config_deploy.yml')
|
119
|
+
# symlinked_services_file = @deploy_dir.join('current', 'config', 'ey_services_config_deploy.yml')
|
120
|
+
#
|
121
|
+
# @deployer.services_fetcher_breaks!
|
122
|
+
# @deployer.deploy
|
123
|
+
#
|
124
|
+
#
|
125
|
+
# shared_services_file.should exist
|
126
|
+
# shared_services_file.should_not be_symlink
|
127
|
+
#
|
128
|
+
# symlinked_services_file.should exist
|
129
|
+
# symlinked_services_file.should be_symlink
|
130
|
+
# end
|
131
|
+
end
|
data/spec/support/integration.rb
CHANGED
@@ -10,11 +10,13 @@ class FullTestDeploy < EY::Serverside::Deploy
|
|
10
10
|
|
11
11
|
# stfu
|
12
12
|
def info(msg)
|
13
|
+
puts msg
|
13
14
|
@infos << msg
|
14
15
|
end
|
15
16
|
|
16
17
|
# no really, stfu
|
17
18
|
def debug(msg)
|
19
|
+
puts msg
|
18
20
|
@debugs << msg
|
19
21
|
end
|
20
22
|
|
@@ -63,16 +65,32 @@ class FullTestDeploy < EY::Serverside::Deploy
|
|
63
65
|
result
|
64
66
|
end
|
65
67
|
|
66
|
-
def get_bundler_installer
|
67
|
-
installer = super
|
68
|
-
installer.options << ' --quiet' # stfu already!
|
69
|
-
installer
|
70
|
-
end
|
71
|
-
|
72
68
|
def deploy
|
73
69
|
yield if block_given?
|
74
70
|
super
|
75
71
|
end
|
72
|
+
|
73
|
+
class MockFetcher
|
74
|
+
def initialize(&block)
|
75
|
+
@block = block
|
76
|
+
end
|
77
|
+
|
78
|
+
def get(app)
|
79
|
+
@block.call(app)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def services_fetcher
|
84
|
+
@mock_fetcher ||= MockFetcher.new { |app| {"some_service_for_#{app}" => {"some_var" => 'some_value'}} }
|
85
|
+
end
|
86
|
+
|
87
|
+
def set_services_fetcher_value(value)
|
88
|
+
@mock_fetcher = MockFetcher.new { |app| value }
|
89
|
+
end
|
90
|
+
|
91
|
+
def services_fetcher_breaks!
|
92
|
+
@mock_fetcher = MockFetcher.new { |app| raise "Server Broken" }
|
93
|
+
end
|
76
94
|
end
|
77
95
|
|
78
96
|
module EY::Serverside::Strategies::IntegrationSpec
|
@@ -109,25 +127,28 @@ module EY::Serverside::Strategies::IntegrationSpec
|
|
109
127
|
|
110
128
|
def gemfile_contents
|
111
129
|
<<-EOF
|
112
|
-
source
|
113
|
-
gem 'rake'
|
114
|
-
|
130
|
+
source :rubygems
|
131
|
+
gem 'rake'
|
132
|
+
gem 'pg'
|
133
|
+
EOF
|
115
134
|
end
|
116
135
|
|
117
|
-
# Generated using Bundler v1.0.
|
136
|
+
# Generated using Bundler v1.0.21
|
118
137
|
def lockfile_contents
|
119
138
|
<<-EOF
|
120
139
|
GEM
|
121
140
|
remote: http://rubygems.org/
|
122
141
|
specs:
|
123
|
-
|
142
|
+
pg (0.11.0)
|
143
|
+
rake (0.9.2.2)
|
124
144
|
|
125
145
|
PLATFORMS
|
126
146
|
ruby
|
127
147
|
|
128
148
|
DEPENDENCIES
|
129
|
-
|
130
|
-
|
149
|
+
pg
|
150
|
+
rake
|
151
|
+
EOF
|
131
152
|
end
|
132
153
|
|
133
154
|
def generate_gemfile_in(dir)
|
metadata
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: engineyard-serverside
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
4
5
|
prerelease:
|
5
|
-
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 5
|
9
|
+
- 12
|
10
|
+
version: 1.5.12
|
6
11
|
platform: ruby
|
7
12
|
authors:
|
8
13
|
- EY Cloud Team
|
@@ -10,31 +15,54 @@ autorequire:
|
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
17
|
|
13
|
-
date: 2011-11-
|
14
|
-
default_executable: engineyard-serverside
|
18
|
+
date: 2011-11-02 00:00:00 Z
|
15
19
|
dependencies:
|
16
20
|
- !ruby/object:Gem::Dependency
|
17
|
-
name:
|
21
|
+
name: ey_instance_api_client
|
22
|
+
prerelease: false
|
18
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
19
24
|
none: false
|
20
25
|
requirements:
|
21
26
|
- - "="
|
22
27
|
- !ruby/object:Gem::Version
|
28
|
+
hash: 17
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
- 1
|
32
|
+
- 5
|
33
|
+
version: 0.1.5
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - "="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 31
|
45
|
+
segments:
|
46
|
+
- 1
|
47
|
+
- 3
|
48
|
+
- 2
|
23
49
|
version: 1.3.2
|
24
50
|
type: :development
|
25
|
-
|
26
|
-
version_requirements: *id001
|
51
|
+
version_requirements: *id002
|
27
52
|
- !ruby/object:Gem::Dependency
|
28
53
|
name: rake
|
29
|
-
|
54
|
+
prerelease: false
|
55
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
30
56
|
none: false
|
31
57
|
requirements:
|
32
58
|
- - ">="
|
33
59
|
- !ruby/object:Gem::Version
|
60
|
+
hash: 3
|
61
|
+
segments:
|
62
|
+
- 0
|
34
63
|
version: "0"
|
35
64
|
type: :development
|
36
|
-
|
37
|
-
version_requirements: *id002
|
65
|
+
version_requirements: *id003
|
38
66
|
description:
|
39
67
|
email: cloud@engineyard.com
|
40
68
|
executables:
|
@@ -255,6 +283,7 @@ files:
|
|
255
283
|
- spec/custom_deploy_spec.rb
|
256
284
|
- spec/deploy_hook_spec.rb
|
257
285
|
- spec/deprecation_spec.rb
|
286
|
+
- spec/fixtures/gitrepo/bar
|
258
287
|
- spec/fixtures/gitrepo/foo
|
259
288
|
- spec/fixtures/gitrepo.tar.gz
|
260
289
|
- spec/fixtures/invalid_hook.rb
|
@@ -278,9 +307,9 @@ files:
|
|
278
307
|
- spec/rails31_deploy_spec.rb
|
279
308
|
- spec/restart_spec.rb
|
280
309
|
- spec/server_spec.rb
|
310
|
+
- spec/services_deploy_spec.rb
|
281
311
|
- spec/spec_helper.rb
|
282
312
|
- spec/support/integration.rb
|
283
|
-
has_rdoc: true
|
284
313
|
homepage: http://github.com/engineyard/engineyard-serverside
|
285
314
|
licenses: []
|
286
315
|
|
@@ -294,7 +323,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
294
323
|
requirements:
|
295
324
|
- - ">="
|
296
325
|
- !ruby/object:Gem::Version
|
297
|
-
hash:
|
326
|
+
hash: 3
|
298
327
|
segments:
|
299
328
|
- 0
|
300
329
|
version: "0"
|
@@ -303,14 +332,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
303
332
|
requirements:
|
304
333
|
- - ">="
|
305
334
|
- !ruby/object:Gem::Version
|
306
|
-
hash:
|
335
|
+
hash: 3
|
307
336
|
segments:
|
308
337
|
- 0
|
309
338
|
version: "0"
|
310
339
|
requirements: []
|
311
340
|
|
312
341
|
rubyforge_project:
|
313
|
-
rubygems_version: 1.
|
342
|
+
rubygems_version: 1.8.11
|
314
343
|
signing_key:
|
315
344
|
specification_version: 3
|
316
345
|
summary: A gem that deploys ruby applications on EY Cloud instances
|
@@ -320,6 +349,7 @@ test_files:
|
|
320
349
|
- spec/custom_deploy_spec.rb
|
321
350
|
- spec/deploy_hook_spec.rb
|
322
351
|
- spec/deprecation_spec.rb
|
352
|
+
- spec/fixtures/gitrepo/bar
|
323
353
|
- spec/fixtures/gitrepo/foo
|
324
354
|
- spec/fixtures/gitrepo.tar.gz
|
325
355
|
- spec/fixtures/invalid_hook.rb
|
@@ -343,5 +373,6 @@ test_files:
|
|
343
373
|
- spec/rails31_deploy_spec.rb
|
344
374
|
- spec/restart_spec.rb
|
345
375
|
- spec/server_spec.rb
|
376
|
+
- spec/services_deploy_spec.rb
|
346
377
|
- spec/spec_helper.rb
|
347
378
|
- spec/support/integration.rb
|