engineyard-serverside 2.0.7 → 2.1.0.pre
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.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
|
|