engineyard-serverside 2.0.7 → 2.1.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/engineyard-serverside.rb +0 -1
- data/lib/engineyard-serverside/cli.rb +44 -42
- data/lib/engineyard-serverside/configuration.rb +55 -4
- data/lib/engineyard-serverside/dependency_manager.rb +17 -0
- data/lib/engineyard-serverside/dependency_manager/base.rb +65 -0
- data/lib/engineyard-serverside/dependency_manager/bundler.rb +124 -0
- data/lib/engineyard-serverside/dependency_manager/bundler_lock.rb +155 -0
- data/lib/engineyard-serverside/dependency_manager/legacy_helpers.rb +24 -0
- data/lib/engineyard-serverside/dependency_manager/npm.rb +16 -0
- data/lib/engineyard-serverside/deploy.rb +86 -178
- data/lib/engineyard-serverside/deprecation.rb +11 -1
- data/lib/engineyard-serverside/paths.rb +6 -0
- data/lib/engineyard-serverside/propagator.rb +2 -2
- data/lib/engineyard-serverside/rails_assets.rb +152 -0
- data/lib/engineyard-serverside/rails_assets/strategy.rb +197 -0
- data/lib/engineyard-serverside/server.rb +5 -0
- data/lib/engineyard-serverside/servers.rb +19 -7
- data/lib/engineyard-serverside/shell.rb +7 -5
- data/lib/engineyard-serverside/shell/command_result.rb +1 -1
- data/lib/engineyard-serverside/strategies/git.rb +14 -4
- data/lib/engineyard-serverside/task.rb +1 -0
- data/lib/engineyard-serverside/version.rb +1 -1
- data/spec/bundler_deploy_spec.rb +36 -33
- data/spec/configuration_spec.rb +5 -4
- data/spec/custom_deploy_spec.rb +11 -9
- data/spec/deploy_hook_spec.rb +10 -3
- data/spec/ey_yml_customized_deploy_spec.rb +1 -1
- data/spec/fixtures/lockfiles/1.0-no-bundler +1 -1
- data/spec/fixtures/lockfiles/1.0.0.rc.1-with-bundler +1 -1
- data/spec/fixtures/lockfiles/1.0.18-do_mysql +1 -1
- data/spec/fixtures/lockfiles/1.0.18-do_postgres +1 -1
- data/spec/fixtures/lockfiles/1.0.18-mysql +1 -1
- data/spec/fixtures/lockfiles/1.0.18-mysql2 +1 -1
- data/spec/fixtures/lockfiles/1.0.18-pg +1 -1
- data/spec/fixtures/lockfiles/1.0.6-no-bundler +2 -2
- data/spec/fixtures/lockfiles/1.0.6-with-any-bundler +2 -2
- data/spec/fixtures/lockfiles/1.0.6-with-bundler +2 -2
- data/spec/fixtures/lockfiles/1.3.1-rails-3.2.13 +112 -0
- data/spec/fixtures/repos/{assets_enabled → assets_detected}/Gemfile +1 -2
- data/spec/fixtures/repos/{assets_enabled → assets_detected}/Gemfile.lock +1 -3
- data/spec/fixtures/repos/{assets_enabled → assets_detected}/README +0 -0
- data/spec/fixtures/repos/assets_detected/Rakefile +5 -0
- data/spec/fixtures/repos/{assets_enabled → assets_detected}/app/assets/empty +0 -0
- data/spec/fixtures/repos/{assets_enabled → assets_detected}/config/application.rb +0 -0
- data/spec/fixtures/repos/assets_detected/config/ey.yml +3 -0
- data/spec/fixtures/repos/assets_disabled/Gemfile +1 -2
- data/spec/fixtures/repos/assets_disabled/Gemfile.lock +1 -3
- data/spec/fixtures/repos/assets_disabled/Rakefile +1 -0
- data/spec/fixtures/repos/assets_disabled/config/ey.yml +3 -0
- data/spec/fixtures/repos/assets_disabled_in_ey_yml/Gemfile +1 -2
- data/spec/fixtures/repos/assets_disabled_in_ey_yml/Gemfile.lock +1 -3
- data/spec/fixtures/repos/assets_disabled_in_ey_yml/Rakefile +1 -0
- data/spec/fixtures/repos/assets_disabled_in_ey_yml/config/ey.yml +1 -0
- data/spec/fixtures/repos/assets_enabled_all/Gemfile +1 -2
- data/spec/fixtures/repos/assets_enabled_all/Gemfile.lock +1 -3
- data/spec/fixtures/repos/assets_enabled_all/Rakefile +1 -0
- data/spec/fixtures/repos/assets_enabled_all/config/ey.yml +1 -0
- data/spec/fixtures/repos/assets_enabled_in_ey_yml/Gemfile +1 -1
- data/spec/fixtures/repos/assets_enabled_in_ey_yml/Gemfile.lock +1 -1
- data/spec/fixtures/repos/assets_enabled_in_ey_yml/Rakefile +1 -0
- data/spec/fixtures/repos/assets_enabled_util_only/Gemfile +1 -2
- data/spec/fixtures/repos/assets_enabled_util_only/Gemfile.lock +1 -3
- data/spec/fixtures/repos/assets_enabled_util_only/Rakefile +1 -0
- data/spec/fixtures/repos/assets_enabled_util_only/config/ey.yml +1 -0
- data/spec/fixtures/repos/assets_in_hook/Gemfile +1 -2
- data/spec/fixtures/repos/assets_in_hook/Gemfile.lock +1 -3
- data/spec/fixtures/repos/assets_in_hook/config/ey.yml +3 -0
- data/spec/fixtures/repos/assets_in_hook/deploy/before_compile_assets.rb +1 -1
- data/spec/fixtures/repos/bundle_fails/Gemfile +1 -0
- data/spec/fixtures/repos/bundle_fails/README +1 -0
- data/spec/fixtures/repos/bundle_fails/deploy/after_bundle.rb +1 -0
- data/spec/fixtures/repos/default/Gemfile +1 -2
- data/spec/fixtures/repos/default/Gemfile.lock +1 -3
- data/spec/fixtures/repos/default/ey.yml +3 -0
- data/spec/fixtures/repos/ey_yml/Gemfile +1 -1
- data/spec/fixtures/repos/ey_yml/Gemfile.lock +1 -1
- data/spec/fixtures/repos/ey_yml/config/ey.yml +11 -7
- data/spec/fixtures/repos/ey_yml_alt/Gemfile +1 -1
- data/spec/fixtures/repos/ey_yml_alt/Gemfile.lock +1 -1
- data/spec/fixtures/repos/no_ey_config/Gemfile +1 -2
- data/spec/fixtures/repos/no_ey_config/Gemfile.lock +1 -3
- data/spec/fixtures/repos/no_ey_config/ey.yml +3 -0
- data/spec/fixtures/repos/no_gemfile_lock/Gemfile +1 -2
- data/spec/fixtures/repos/no_gemfile_lock/ey.yml +3 -0
- data/spec/fixtures/repos/sqlite3/Gemfile +1 -1
- data/spec/fixtures/repos/sqlite3/Gemfile.lock +1 -1
- data/spec/lockfile_parser_spec.rb +25 -11
- data/spec/rails31_deploy_spec.rb +46 -5
- data/spec/restart_spec.rb +3 -3
- data/spec/services_deploy_spec.rb +89 -86
- data/spec/shell_spec.rb +0 -8
- data/spec/spec_helper.rb +81 -36
- data/spec/sqlite3_deploy_spec.rb +4 -5
- data/spec/support/integration.rb +22 -37
- metadata +167 -154
- data/lib/engineyard-serverside/lockfile_parser.rb +0 -101
- data/lib/engineyard-serverside/rails_asset_support.rb +0 -132
- data/spec/fixtures/repos/assets_enabled/Rakefile +0 -5
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'engineyard-serverside/dependency_manager/bundler'
|
2
|
+
|
3
|
+
module EY
|
4
|
+
module Serverside
|
5
|
+
module DependencyManager
|
6
|
+
class BundlerLock < Bundler
|
7
|
+
def detected?
|
8
|
+
gemfile? && lockfile?
|
9
|
+
end
|
10
|
+
|
11
|
+
def check
|
12
|
+
shell.status "Gemfile and Gemfile.lock found"
|
13
|
+
|
14
|
+
if config.check_database_adapter? && !lockfile.any_database_adapter?
|
15
|
+
shell.warning <<-WARN
|
16
|
+
Gemfile.lock does not contain a recognized database adapter.
|
17
|
+
A database-adapter gem such as pg, mysql2, mysql, or do_mysql was expected.
|
18
|
+
This can prevent applications that use PostgreSQL or MySQL from booting.
|
19
|
+
|
20
|
+
To fix, add any needed adapter to your Gemfile, bundle, commit, and redeploy.
|
21
|
+
Applications not using PostgreSQL or MySQL can safely ignore this warning by
|
22
|
+
adding ignore_database_adapter_warning: true to the application's ey.yml file
|
23
|
+
under this environment's name and adding the file to your repository.
|
24
|
+
WARN
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def uses_sqlite3?
|
29
|
+
lockfile.uses_sqlite3?
|
30
|
+
end
|
31
|
+
|
32
|
+
def check_ey_config
|
33
|
+
unless lockfile.has_ey_config?
|
34
|
+
shell.warning "Gemfile.lock does not contain ey_config.\nAdd gem 'ey_config' to get access to service configuration through EY::Config."
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def rails_version
|
39
|
+
lockfile.rails_version
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def lockfile_path
|
45
|
+
paths.gemfile_lock
|
46
|
+
end
|
47
|
+
|
48
|
+
def lockfile
|
49
|
+
@lockfile ||= Lockfile.new(lockfile_path.read, self.class.default_version)
|
50
|
+
end
|
51
|
+
|
52
|
+
# deployment mode is not supported without a Gemfile.lock
|
53
|
+
def bundle_install_options
|
54
|
+
super + ["--deployment"]
|
55
|
+
end
|
56
|
+
|
57
|
+
def bundler_version
|
58
|
+
@bundler_version ||= lockfile.bundler_version || super
|
59
|
+
end
|
60
|
+
|
61
|
+
class Lockfile
|
62
|
+
attr_reader :bundler_version
|
63
|
+
|
64
|
+
def initialize(lockfile_contents, default = EY::Serverside::DependencyManager::Bundler.default_version)
|
65
|
+
@contents = lockfile_contents
|
66
|
+
@default = default
|
67
|
+
@default_gem_version = Gem::Version.new(@default)
|
68
|
+
parse
|
69
|
+
end
|
70
|
+
|
71
|
+
def has_ey_config?
|
72
|
+
!!@contents.index(/^\s+ey_config\s\([^\)]+\)$/)
|
73
|
+
end
|
74
|
+
|
75
|
+
def rails_version
|
76
|
+
section = dependencies_section
|
77
|
+
if section.empty?
|
78
|
+
return nil
|
79
|
+
end
|
80
|
+
result = scan_gem('rails', section)
|
81
|
+
result ? result.last : nil
|
82
|
+
end
|
83
|
+
|
84
|
+
def any_database_adapter?
|
85
|
+
any_ruby_adapter = %w[mysql2 mysql do_mysql pg do_postgres].any? do |type|
|
86
|
+
@contents.index(/^\s+#{type}\s\([^\)]+\)$/)
|
87
|
+
end
|
88
|
+
|
89
|
+
any_jruby_adapter = %w[mysql postgresql postgres].any? do |type|
|
90
|
+
@contents.index(/^\s+jdbc-#{type}\s\([^\)]+\)$/) || @contents.index(/^\s+activerecord-jdbc#{type}-adapter\s\([^\)]+\)$/)
|
91
|
+
end
|
92
|
+
|
93
|
+
any_ruby_adapter || any_jruby_adapter
|
94
|
+
end
|
95
|
+
|
96
|
+
def uses_sqlite3?
|
97
|
+
!any_database_adapter? && @contents.index(/^\s+sqlite3\s\([^\)]+\)$/)
|
98
|
+
end
|
99
|
+
|
100
|
+
def parse
|
101
|
+
parse_from_metadata ||
|
102
|
+
parse_from_dependencies ||
|
103
|
+
raise("Malformed or pre bundler-1.0.0 Gemfile.lock: #{@contents[0,50]}...")
|
104
|
+
end
|
105
|
+
|
106
|
+
def slice_section(header)
|
107
|
+
if start = @contents.index(/^#{header}/)
|
108
|
+
finish = @contents.index(/(^\S|\Z)/, start + header.length)
|
109
|
+
@contents.slice(start..finish)
|
110
|
+
else
|
111
|
+
""
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def parse_from_metadata
|
116
|
+
section = slice_section('METADATA')
|
117
|
+
|
118
|
+
if section.empty?
|
119
|
+
return nil
|
120
|
+
end
|
121
|
+
|
122
|
+
result = section.scan(/^\s*version:\s*(.*)$/).first
|
123
|
+
@bundler_version = result ? result.first : @default
|
124
|
+
end
|
125
|
+
|
126
|
+
def dependencies_section
|
127
|
+
@dependencies_section ||= slice_section('DEPENDENCIES')
|
128
|
+
end
|
129
|
+
|
130
|
+
def parse_from_dependencies
|
131
|
+
section = dependencies_section
|
132
|
+
if section.empty?
|
133
|
+
return nil
|
134
|
+
end
|
135
|
+
|
136
|
+
result = scan_gem('bundler', section)
|
137
|
+
bundler_version = result ? result.last : nil
|
138
|
+
version_qualifier = result ? result.first : nil
|
139
|
+
@bundler_version = fetch_version(version_qualifier, bundler_version)
|
140
|
+
end
|
141
|
+
|
142
|
+
def fetch_version(operator, version)
|
143
|
+
return version || @default unless operator && version
|
144
|
+
req = Gem::Requirement.new(["#{operator} #{version}"])
|
145
|
+
req.satisfied_by?(@default_gem_version) ? @default : version
|
146
|
+
end
|
147
|
+
|
148
|
+
def scan_gem(gem, dep_section)
|
149
|
+
dep_section.scan(/^\s*#{Regexp.escape(gem)}\s*\((>?=|~>)\s*([^,\)]+)/).first
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module EY
|
2
|
+
module Serverside
|
3
|
+
module DependencyManager
|
4
|
+
module LegacyHelpers
|
5
|
+
[
|
6
|
+
:gemfile?,
|
7
|
+
:bundler_config,
|
8
|
+
:lockfile,
|
9
|
+
:check_ruby_bundler,
|
10
|
+
:clean_bundle_on_system_version_change,
|
11
|
+
:write_system_version,
|
12
|
+
:check_node_npm,
|
13
|
+
:clean_environment,
|
14
|
+
].each do |meth|
|
15
|
+
define_method(meth) do |*a|
|
16
|
+
if dependency_manager.respond_to?(meth)
|
17
|
+
dependency_manager.send(meth)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module EY
|
2
|
+
module Serverside
|
3
|
+
module DependencyManager
|
4
|
+
class Npm < Base
|
5
|
+
def detected?
|
6
|
+
paths.package_json.exist?
|
7
|
+
end
|
8
|
+
|
9
|
+
def install
|
10
|
+
shell.status "Installing npm packages (package.json detected)"
|
11
|
+
run "cd #{paths.active_release} && npm install"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -1,14 +1,15 @@
|
|
1
|
-
#
|
1
|
+
# Inspired by capistrano, thanks Jamis!
|
2
2
|
require 'base64'
|
3
|
-
require 'fileutils'
|
4
3
|
require 'multi_json'
|
5
|
-
require 'engineyard-serverside/
|
4
|
+
require 'engineyard-serverside/rails_assets'
|
6
5
|
require 'engineyard-serverside/maintenance'
|
6
|
+
require 'engineyard-serverside/dependency_manager'
|
7
|
+
require 'engineyard-serverside/dependency_manager/legacy_helpers'
|
7
8
|
|
8
9
|
module EY
|
9
10
|
module Serverside
|
10
11
|
class DeployBase < Task
|
11
|
-
include ::EY::Serverside::
|
12
|
+
include ::EY::Serverside::DependencyManager::LegacyHelpers
|
12
13
|
|
13
14
|
# default task
|
14
15
|
def deploy
|
@@ -31,7 +32,6 @@ module EY
|
|
31
32
|
create_revision_file
|
32
33
|
run_with_callbacks(:bundle)
|
33
34
|
setup_services
|
34
|
-
check_for_ey_config
|
35
35
|
symlink_configs
|
36
36
|
setup_sqlite3_if_necessary
|
37
37
|
run_with_callbacks(:compile_assets) # defined in RailsAssetSupport
|
@@ -72,60 +72,12 @@ module EY
|
|
72
72
|
strategy.short_log_message(revision)
|
73
73
|
end
|
74
74
|
|
75
|
-
def
|
76
|
-
|
77
|
-
return {} unless result.is_a?(Hash)
|
78
|
-
result
|
79
|
-
rescue
|
80
|
-
{}
|
81
|
-
end
|
82
|
-
|
83
|
-
def check_for_ey_config
|
84
|
-
if gemfile? && lockfile
|
85
|
-
configured_services = parse_configured_services
|
86
|
-
if !configured_services.empty? && !lockfile.has_ey_config?
|
87
|
-
shell.warning "Gemfile.lock does not contain ey_config. Add it to get EY::Config access to: #{configured_services.keys.join(', ')}."
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
# The nodatabase.yml file is dropped by server configuration when there is
|
93
|
-
# no database in the cluster.
|
94
|
-
def has_database?
|
95
|
-
paths.shared_config.join('database.yml').exist? &&
|
96
|
-
!paths.shared_config.join('nodatabase.yml').exist?
|
75
|
+
def check_repository
|
76
|
+
check_dependencies
|
97
77
|
end
|
98
78
|
|
99
|
-
def
|
100
|
-
|
101
|
-
shell.status "Gemfile found."
|
102
|
-
if lockfile
|
103
|
-
shell.status "Gemfile.lock found."
|
104
|
-
if !config.ignore_database_adapter_warning? && has_database? && !lockfile.any_database_adapter?
|
105
|
-
shell.warning <<-WARN
|
106
|
-
Gemfile.lock does not contain a recognized database adapter.
|
107
|
-
A database-adapter gem such as pg, mysql2, mysql, or do_mysql was expected.
|
108
|
-
This can prevent applications that use PostgreSQL or MySQL from booting.
|
109
|
-
|
110
|
-
To fix, add any needed adapter to your Gemfile, bundle, commit, and redeploy.
|
111
|
-
Applications not using PostgreSQL or MySQL can safely ignore this warning by
|
112
|
-
adding ignore_database_adapter_warning: true to the application's ey.yml file
|
113
|
-
under this environment's name and adding the file to your repository.
|
114
|
-
WARN
|
115
|
-
end
|
116
|
-
else
|
117
|
-
shell.warning <<-WARN
|
118
|
-
Gemfile.lock is missing!
|
119
|
-
You can get different versions of gems in production than what you tested with.
|
120
|
-
You can get different versions of gems on every deployment even if your Gemfile hasn't changed.
|
121
|
-
Deploying will take longer.
|
122
|
-
|
123
|
-
To fix this problem, commit your Gemfile.lock to your repository and redeploy.
|
124
|
-
WARN
|
125
|
-
end
|
126
|
-
else
|
127
|
-
shell.status "No Gemfile. Deploying without bundler support."
|
128
|
-
end
|
79
|
+
def check_dependencies
|
80
|
+
dependency_manager.check
|
129
81
|
end
|
130
82
|
|
131
83
|
def restart_with_maintenance_page
|
@@ -153,7 +105,7 @@ To fix this problem, commit your Gemfile.lock to your repository and redeploy.
|
|
153
105
|
# task
|
154
106
|
def push_code
|
155
107
|
shell.status "Pushing code to all servers"
|
156
|
-
servers.remote.run_on_each do |server|
|
108
|
+
servers.remote.run_on_each(shell) do |server|
|
157
109
|
cmd = server.sync_directory_command(paths.repository_cache)
|
158
110
|
shell.logged_system(cmd)
|
159
111
|
end
|
@@ -173,9 +125,8 @@ To fix this problem, commit your Gemfile.lock to your repository and redeploy.
|
|
173
125
|
%{LANG="en_US.UTF-8" /engineyard/bin/app_#{config.app} deploy}
|
174
126
|
end
|
175
127
|
|
176
|
-
|
177
|
-
|
178
|
-
%Q[export GIT_SSH="#{ssh_executable}" && export LANG="en_US.UTF-8" && unset RUBYOPT BUNDLE_PATH BUNDLE_FROZEN BUNDLE_WITHOUT BUNDLE_BIN BUNDLE_GEMFILE]
|
128
|
+
def ensure_git_ssh_wrapper
|
129
|
+
ENV['GIT_SSH'] = ssh_executable.to_s
|
179
130
|
end
|
180
131
|
|
181
132
|
# create ssh wrapper on all servers
|
@@ -206,18 +157,17 @@ chmod 0700 #{path}
|
|
206
157
|
SCRIPT
|
207
158
|
end
|
208
159
|
|
209
|
-
# task
|
210
160
|
def bundle
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
161
|
+
install_dependencies
|
162
|
+
end
|
163
|
+
|
164
|
+
def install_dependencies
|
165
|
+
dependency_manager.install
|
215
166
|
end
|
216
167
|
|
217
168
|
# task
|
218
169
|
def cleanup_old_releases
|
219
170
|
clean_release_directory(paths.releases)
|
220
|
-
clean_release_directory(paths.releases_failed)
|
221
171
|
end
|
222
172
|
|
223
173
|
# Remove all but the most-recent +count+ releases from the specified
|
@@ -272,39 +222,31 @@ chmod 0700 #{path}
|
|
272
222
|
def copy_repository_cache
|
273
223
|
shell.status "Copying to #{paths.active_release}"
|
274
224
|
exclusions = Array(config.copy_exclude).map { |e| %|--exclude="#{e}"| }.join(' ')
|
275
|
-
run("mkdir -p #{paths.active_release} #{paths.
|
225
|
+
run("mkdir -p #{paths.active_release} #{paths.shared_config} && rsync -aq #{exclusions} #{paths.repository_cache}/ #{paths.active_release}")
|
276
226
|
|
277
227
|
shell.status "Ensuring proper ownership."
|
278
|
-
|
228
|
+
ensure_ownership(paths.active_release)
|
279
229
|
end
|
280
230
|
|
281
231
|
def create_revision_file
|
282
232
|
run create_revision_file_command
|
283
233
|
end
|
284
234
|
|
285
|
-
def services_command_check
|
286
|
-
"which /usr/local/ey_resin/ruby/bin/ey-services-setup >/dev/null 2>&1"
|
287
|
-
end
|
288
|
-
|
289
|
-
def services_setup_command
|
290
|
-
"/usr/local/ey_resin/ruby/bin/ey-services-setup #{config.app}"
|
291
|
-
end
|
292
|
-
|
293
235
|
def setup_services
|
294
236
|
shell.status "Setting up external services."
|
295
|
-
previously_configured_services =
|
237
|
+
previously_configured_services = config.configured_services
|
296
238
|
|
297
239
|
begin
|
298
|
-
sudo(
|
299
|
-
rescue
|
240
|
+
sudo(config.services_check_command)
|
241
|
+
rescue EY::Serverside::RemoteFailure
|
300
242
|
shell.info "Could not setup services. Upgrade your environment to get services configuration."
|
301
243
|
return
|
302
244
|
end
|
303
245
|
|
304
246
|
begin
|
305
|
-
sudo(services_setup_command)
|
306
|
-
rescue
|
307
|
-
|
247
|
+
sudo(config.services_setup_command)
|
248
|
+
rescue EY::Serverside::RemoteFailure => e
|
249
|
+
if previously_configured_services
|
308
250
|
shell.warning <<-WARNING
|
309
251
|
External services configuration not updated. Using previous version.
|
310
252
|
Deploy again if your services configuration appears incomplete or out of date.
|
@@ -312,32 +254,40 @@ Deploy again if your services configuration appears incomplete or out of date.
|
|
312
254
|
WARNING
|
313
255
|
end
|
314
256
|
end
|
257
|
+
|
258
|
+
if services = config.configured_services
|
259
|
+
shell.status "Services configured: #{services.join(', ')}"
|
260
|
+
dependency_manager.check_ey_config
|
261
|
+
end
|
315
262
|
end
|
316
263
|
|
317
264
|
def setup_sqlite3_if_necessary
|
318
|
-
if
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
265
|
+
if dependency_manager.uses_sqlite3?
|
266
|
+
shell.status "Setting up SQLite3 Database for compatibility with application's chosen adapter"
|
267
|
+
shell.warning "SQLite3 cannot persist across servers. Please upgrade to a supported database."
|
268
|
+
|
269
|
+
shell.substatus "Create databases directory if needed"
|
270
|
+
run "mkdir -p #{paths.shared}/databases"
|
271
|
+
|
272
|
+
shell.substatus "Create SQLite database if needed"
|
273
|
+
run "touch #{paths.shared}/databases/#{config.framework_env}.sqlite3"
|
274
|
+
|
275
|
+
shell.substatus "Create config directory if needed"
|
276
|
+
run "mkdir -p #{paths.active_release_config}"
|
277
|
+
|
278
|
+
shell.substatus "Generating SQLite config"
|
279
|
+
run <<-WRAP
|
324
280
|
cat > #{paths.shared_config}/database.sqlite3.yml<<'YML'
|
325
281
|
#{config.framework_env}:
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
282
|
+
adapter: sqlite3
|
283
|
+
database: #{paths.shared}/databases/#{config.framework_env}.sqlite3
|
284
|
+
pool: 5
|
285
|
+
timeout: 5000
|
330
286
|
YML
|
331
|
-
WRAP
|
332
|
-
["Symlink database.yml", "ln -nfs #{paths.shared_config}/database.sqlite3.yml #{paths.active_release_config}/database.yml"],
|
333
|
-
].each do |what, cmd|
|
334
|
-
shell.status "#{what}"
|
335
|
-
run(cmd)
|
336
|
-
end
|
287
|
+
WRAP
|
337
288
|
|
338
|
-
|
339
|
-
|
340
|
-
sudo "chown -R #{owner} #{paths.active_release}"
|
289
|
+
shell.substatus "Symlink database.yml"
|
290
|
+
run "ln -nfs #{paths.shared_config}/database.sqlite3.yml #{paths.active_release_config}/database.yml"
|
341
291
|
end
|
342
292
|
end
|
343
293
|
|
@@ -347,9 +297,6 @@ WRAP
|
|
347
297
|
shell.substatus what
|
348
298
|
run(cmd)
|
349
299
|
end
|
350
|
-
owner = [config.user, config.group].join(':')
|
351
|
-
shell.status "Setting ownership to #{owner}"
|
352
|
-
sudo "chown -R #{owner} #{paths.active_release}"
|
353
300
|
end
|
354
301
|
|
355
302
|
def symlink_tasks
|
@@ -372,14 +319,31 @@ WRAP
|
|
372
319
|
# task
|
373
320
|
def symlink
|
374
321
|
shell.status "Symlinking code."
|
375
|
-
run
|
322
|
+
run move_symlink(paths.active_release, paths.current, "deploying")
|
323
|
+
ensure_ownership(paths.current)
|
376
324
|
@symlink_changed = true
|
377
325
|
rescue Exception
|
378
|
-
sudo
|
326
|
+
sudo move_symlink(paths.previous_release(paths.active_release), paths.current, "reverting")
|
327
|
+
ensure_ownership(paths.current)
|
379
328
|
@symlink_changed = false
|
380
329
|
raise
|
381
330
|
end
|
382
331
|
|
332
|
+
def ensure_ownership(*targets)
|
333
|
+
sudo "find #{targets.join(' ')} -not -user #{config.user} -or -not -group #{config.group} -exec chown #{config.user}:#{config.group} {} +"
|
334
|
+
end
|
335
|
+
|
336
|
+
# Move a symlink as atomically as we can.
|
337
|
+
#
|
338
|
+
# mv -T renames 'next' to 'current' instead of moving 'next' to current/next'
|
339
|
+
# mv -T isn't available on OS X and maybe elsewhere, so fallback to rm && ln
|
340
|
+
def move_symlink(source, link, name)
|
341
|
+
next_link = link.dirname.join(name)
|
342
|
+
mv_t = "ln -nfs #{source} #{next_link} && mv -T #{next_link} #{link} >/dev/null 2>&1"
|
343
|
+
rm_ln = "rm -rf #{next_link} #{link} && ln -nfs #{source} #{link}"
|
344
|
+
"((#{mv_t}) || (#{rm_ln}))"
|
345
|
+
end
|
346
|
+
|
383
347
|
def callback(what)
|
384
348
|
@callbacks_reached ||= true
|
385
349
|
if paths.deploy_hook(what).exist?
|
@@ -402,7 +366,7 @@ WRAP
|
|
402
366
|
# Rollback doesn't know about the repository location (nor
|
403
367
|
# should it need to), but it would like to use #short_log_message.
|
404
368
|
def strategy
|
405
|
-
|
369
|
+
ensure_git_ssh_wrapper
|
406
370
|
@strategy ||= config.strategy_class.new(
|
407
371
|
shell,
|
408
372
|
:verbose => config.verbose,
|
@@ -412,10 +376,7 @@ WRAP
|
|
412
376
|
:ref => config[:branch]
|
413
377
|
)
|
414
378
|
end
|
415
|
-
|
416
|
-
def gemfile?
|
417
|
-
paths.gemfile.exist?
|
418
|
-
end
|
379
|
+
public :strategy
|
419
380
|
|
420
381
|
def base_callback_command_for(what)
|
421
382
|
cmd = [About.binary, 'hook', what.to_s]
|
@@ -453,82 +414,29 @@ WRAP
|
|
453
414
|
end
|
454
415
|
end
|
455
416
|
|
456
|
-
def maintenance
|
457
|
-
@maintenance ||= Maintenance.new(servers, config, shell)
|
458
|
-
end
|
459
|
-
|
460
417
|
def with_failed_release_cleanup
|
461
418
|
yield
|
462
|
-
rescue Exception
|
419
|
+
rescue Exception => e
|
463
420
|
shell.status "Release #{paths.active_release} failed, saving release to #{paths.releases_failed}."
|
464
|
-
|
421
|
+
run "mkdir -p #{paths.releases_failed}"
|
422
|
+
ensure_ownership(paths.active_release, paths.releases_failed)
|
423
|
+
run "mv #{paths.active_release} #{paths.releases_failed}"
|
465
424
|
clean_release_directory(paths.releases_failed)
|
466
|
-
raise
|
467
|
-
end
|
468
|
-
|
469
|
-
def bundler_config
|
470
|
-
version = LockfileParser.default_version
|
471
|
-
options = [
|
472
|
-
"--gemfile #{paths.gemfile}",
|
473
|
-
"--path #{paths.bundled_gems}",
|
474
|
-
"--binstubs #{paths.binstubs}",
|
475
|
-
"--without #{config.bundle_without}"
|
476
|
-
]
|
477
|
-
|
478
|
-
if lockfile
|
479
|
-
version = lockfile.bundler_version
|
480
|
-
options.unshift('--deployment') # deployment mode is not supported without a Gemfile.lock
|
481
|
-
end
|
482
|
-
|
483
|
-
return [version, options.join(' ')]
|
484
|
-
end
|
485
|
-
|
486
|
-
def lockfile
|
487
|
-
lockfile_path = paths.gemfile_lock
|
488
|
-
if lockfile_path.exist?
|
489
|
-
@lockfile_parser ||= LockfileParser.new(lockfile_path.read)
|
490
|
-
else
|
491
|
-
nil
|
492
|
-
end
|
493
|
-
end
|
494
|
-
|
495
|
-
def check_ruby_bundler
|
496
|
-
if gemfile?
|
497
|
-
shell.status "Bundling gems..."
|
498
|
-
|
499
|
-
clean_bundle_on_system_version_change
|
500
|
-
|
501
|
-
bundler_version, install_switches = bundler_config
|
502
|
-
sudo "#{clean_environment} && #{About.binary} install_bundler #{bundler_version}"
|
503
|
-
run "#{clean_environment} && cd #{paths.active_release} && ruby -S bundle _#{bundler_version}_ install #{install_switches}"
|
504
|
-
|
505
|
-
write_system_version
|
506
|
-
end
|
425
|
+
raise e
|
507
426
|
end
|
508
427
|
|
509
|
-
def
|
510
|
-
|
511
|
-
check_ruby = "#{config.ruby_version_command} | diff - #{paths.ruby_version} >/dev/null 2>&1"
|
512
|
-
check_system = "#{config.system_version_command} | diff - #{paths.system_version} >/dev/null 2>&1"
|
513
|
-
say_cleaning = "echo 'New deploy or system version change detected, cleaning bundled gems.'"
|
514
|
-
clean_bundle = "rm -Rf #{paths.bundled_gems}"
|
515
|
-
|
516
|
-
run "#{check_ruby} && #{check_system} || (#{say_cleaning} && #{clean_bundle})"
|
428
|
+
def maintenance
|
429
|
+
@maintenance ||= Maintenance.new(servers, config, shell)
|
517
430
|
end
|
518
431
|
|
519
|
-
def
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
run "mkdir -p #{paths.bundled_gems} && chown #{config.user}:#{config.group} #{paths.bundled_gems}"
|
524
|
-
run "#{store_ruby_version} && #{store_system_version}"
|
432
|
+
def dependency_manager
|
433
|
+
ensure_git_ssh_wrapper
|
434
|
+
@dependency_manager ||= DependencyManager.detect(servers, config, shell, self)
|
525
435
|
end
|
436
|
+
public :dependency_manager # FIXME
|
526
437
|
|
527
|
-
def
|
528
|
-
|
529
|
-
shell.info "~> package.json detected, installing npm packages"
|
530
|
-
run "cd #{paths.active_release} && npm install"
|
531
|
-
end
|
438
|
+
def compile_assets
|
439
|
+
RailsAssets.detect_and_compile(config, shell, self)
|
532
440
|
end
|
533
441
|
end # DeployBase
|
534
442
|
|