dkdeploy-core 8.0.2 → 9.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.rubocop.yml +9 -0
- data/.travis.yml +13 -0
- data/CHANGELOG.md +38 -0
- data/CONTRIBUTORS.md +2 -0
- data/LICENSE +1 -1
- data/README.md +8 -5
- data/Vagrantfile +3 -10
- data/assets/dkdeploy-logo.png +0 -0
- data/config/vm/cookbooks/dkdeploy-core/recipes/default.rb +13 -1
- data/config/vm/cookbooks/dkdeploy-core/templates/my_extra_settings.erb +6 -0
- data/dkdeploy-core.gemspec +11 -12
- data/features/assets.feature +24 -26
- data/features/db.feature +4 -0
- data/features/mysql.feature +27 -0
- data/features/support/env.rb +1 -1
- data/lib/capistrano/dkdeploy/core.rb +11 -22
- data/lib/dkdeploy/constants.rb +5 -73
- data/lib/dkdeploy/core/version.rb +2 -2
- data/lib/dkdeploy/dsl.rb +1 -1
- data/lib/dkdeploy/helpers/assets.rb +0 -1
- data/lib/dkdeploy/helpers/db.rb +1 -1
- data/lib/dkdeploy/helpers/mysql.rb +17 -0
- data/lib/dkdeploy/i18n.rb +6 -0
- data/lib/dkdeploy/interaction_handler/mysql.rb +38 -0
- data/lib/dkdeploy/interaction_handler/password.rb +3 -2
- data/lib/dkdeploy/scm/copy.rake +76 -0
- data/lib/dkdeploy/scm/copy.rb +85 -0
- data/lib/dkdeploy/tasks/apache.rake +0 -1
- data/lib/dkdeploy/tasks/assets.rake +0 -1
- data/lib/dkdeploy/tasks/bower.rake +0 -1
- data/lib/dkdeploy/tasks/db.rake +20 -28
- data/lib/dkdeploy/tasks/deploy.rake +1 -11
- data/lib/dkdeploy/tasks/enhanced_symlinks.rake +3 -3
- data/lib/dkdeploy/tasks/file_access.rake +8 -9
- data/lib/dkdeploy/tasks/maintenance.rake +0 -1
- data/lib/dkdeploy/tasks/mysql.rake +50 -0
- data/lib/dkdeploy/tasks/project_version.rake +0 -1
- data/lib/dkdeploy/tasks/utils.rake +6 -2
- data/spec/fixtures/application/Gemfile +1 -1
- data/spec/fixtures/application/config/deploy/dev.rb +6 -3
- data/spec/fixtures/application/config/deploy.rb +42 -5
- data/spec/fixtures/application/config/preseed/default_content.sql.gz +0 -0
- data/spec/fixtures/application/config/preseed/download.tar.gz +0 -0
- data/spec/fixtures/capistrano/configuration/add_output_after_create_symlink.rb +1 -2
- data/spec/fixtures/capistrano/configuration/custom_compass_sources.rb +2 -2
- metadata +41 -55
- data/lib/dkdeploy/copy.rb +0 -121
- data/lib/dkdeploy/tasks/copy.rake +0 -26
- data/spec/fixtures/application/config/preseed/fileadmin.tar.gz +0 -0
- data/spec/fixtures/application/config/preseed/uploads.tar.gz +0 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
module Dkdeploy
|
2
|
+
module InteractionHandler
|
3
|
+
# Interaction handler for mysql
|
4
|
+
class MySql
|
5
|
+
# Interaction handler for sending password to MySQL client
|
6
|
+
# This InteractionHandler provides output of the error code if MySQL
|
7
|
+
# answers with an error to the command.
|
8
|
+
#
|
9
|
+
# @attr [String] password The password to send to terminal
|
10
|
+
def initialize(password)
|
11
|
+
@password = password
|
12
|
+
# these two are declared as instance variables because the on_data method is called multiple times
|
13
|
+
@return_message = ''
|
14
|
+
@mysql_error_seen = false
|
15
|
+
end
|
16
|
+
|
17
|
+
# Method to send password to terminal
|
18
|
+
#
|
19
|
+
# @param [SSHKit::Command] _command
|
20
|
+
# @param [Symbol] _stream_name
|
21
|
+
# @param [String] data
|
22
|
+
# @param [Net::SSH::Connection::Channel] channel
|
23
|
+
def on_data(_command, _stream_name, data, channel)
|
24
|
+
if data =~ /.*password.*/i
|
25
|
+
channel.send_data("#{@password}\n")
|
26
|
+
else
|
27
|
+
@mysql_error_seen = true if data =~ /.*ERROR.*/i
|
28
|
+
return raise 'Unexpected data from stream. Can not send password to undefined stream' unless @mysql_error_seen
|
29
|
+
# combine the multiple lines from error message. The fact that the error message will be shown multiple times is simply ignored
|
30
|
+
@return_message << data
|
31
|
+
message = 'Error on executing MySQL command! Response (error code) is: '
|
32
|
+
SSHKit.config.output.send(:error, "#{message}\n #{@return_message}")
|
33
|
+
raise 'InteractionHandler caught a MySQL error'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
module Dkdeploy
|
2
2
|
module InteractionHandler
|
3
3
|
# Interaction handler for password
|
4
|
-
#
|
5
|
-
# @attr [String] password The password to send to terminal
|
6
4
|
class Password
|
5
|
+
# Interaction handler for password
|
6
|
+
#
|
7
|
+
# @attr [String] password The password to send to terminal
|
7
8
|
def initialize(password)
|
8
9
|
@password = password
|
9
10
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# This trick lets us access the copy plugin within `on` blocks.
|
2
|
+
copy_plugin = self
|
3
|
+
|
4
|
+
namespace :copy do
|
5
|
+
desc 'Check if all configuration variables and copy sources exist'
|
6
|
+
task :check do
|
7
|
+
run_locally do
|
8
|
+
unless Dir.exist? copy_source
|
9
|
+
fatal I18n.t('directory.not_exists', name: copy_source, scope: :dkdeploy)
|
10
|
+
exit 1
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Upload the source repository to releases'
|
16
|
+
task create_release: %i[build_source_archive copy_archive_to_server clean_up_temporary_sources]
|
17
|
+
|
18
|
+
# Builds a tar archive in a temporary directory
|
19
|
+
# excluding files and folders matching the configured pattern.
|
20
|
+
#
|
21
|
+
task :build_source_archive do
|
22
|
+
run_locally do
|
23
|
+
info I18n.t('tasks.copy.archive.generate', scope: :dkdeploy)
|
24
|
+
|
25
|
+
# generate an exclude.txt file with the patterns to be excluded
|
26
|
+
exclude_content = copy_exclude.join("\n")
|
27
|
+
File.write(copy_plugin.local_exclude_path, exclude_content)
|
28
|
+
|
29
|
+
# build the tar archive excluding the patterns from exclude.txt
|
30
|
+
within copy_source do
|
31
|
+
execute :tar, '-X ' + copy_plugin.local_exclude_path, '-cpzf', copy_plugin.local_archive_path, '.'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Copies the tar archive on the remote server
|
37
|
+
# extracting it to the configured directory.
|
38
|
+
#
|
39
|
+
task :copy_archive_to_server do
|
40
|
+
on release_roles :all do
|
41
|
+
info I18n.t('file.upload', file: 'archive', target: copy_plugin.remote_tmp_dir, scope: :dkdeploy)
|
42
|
+
execute :mkdir, '-p', copy_plugin.remote_tmp_dir
|
43
|
+
|
44
|
+
upload! copy_plugin.local_archive_path, copy_plugin.remote_tmp_dir
|
45
|
+
|
46
|
+
info I18n.t('directory.create', directory: release_path, scope: :dkdeploy)
|
47
|
+
execute :mkdir, '-p', release_path
|
48
|
+
|
49
|
+
within release_path do
|
50
|
+
info I18n.t('tasks.copy.archive.extract', target: release_path, scope: :dkdeploy)
|
51
|
+
execute :tar, '-xpzf', copy_plugin.remote_archive_path
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Cleans up the local and remote temporary directories
|
57
|
+
#
|
58
|
+
task :clean_up_temporary_sources do
|
59
|
+
# remove the local temporary directory
|
60
|
+
run_locally do
|
61
|
+
info I18n.t('file.remove', path: copy_plugin.local_tmp_dir, scope: :dkdeploy)
|
62
|
+
execute :rm, '-rf', copy_plugin.local_tmp_dir
|
63
|
+
end
|
64
|
+
|
65
|
+
# removes the remote temp path including the uploaded archive
|
66
|
+
on release_roles :all do
|
67
|
+
info I18n.t('file.remove', path: copy_plugin.remote_archive_path, scope: :dkdeploy)
|
68
|
+
execute :rm, '-rf', copy_plugin.remote_tmp_dir
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
desc 'Determine the revision that will be deployed'
|
73
|
+
task :set_current_revision do
|
74
|
+
set :current_revision, I18n.t('log.revision_log_message', copy_source: fetch(:copy_source), time: Time.now, scope: :dkdeploy)
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
require 'capistrano/scm/plugin'
|
3
|
+
require 'capistrano/i18n'
|
4
|
+
require 'dkdeploy/i18n'
|
5
|
+
|
6
|
+
include Capistrano::DSL
|
7
|
+
|
8
|
+
module Dkdeploy
|
9
|
+
module SCM
|
10
|
+
# Class for the capistrano copy
|
11
|
+
#
|
12
|
+
class Copy < Capistrano::SCM::Plugin
|
13
|
+
def set_defaults
|
14
|
+
set_if_empty :copy_source, 'htdocs'
|
15
|
+
set_if_empty :copy_exclude, Array[
|
16
|
+
'vendor/bundle/**',
|
17
|
+
'Gemfile*',
|
18
|
+
'**/.git',
|
19
|
+
'**/.svn',
|
20
|
+
'**/.DS_Store',
|
21
|
+
'.settings',
|
22
|
+
'.project',
|
23
|
+
'.buildpath',
|
24
|
+
'Capfile',
|
25
|
+
'Thumbs.db',
|
26
|
+
'composer.lock'
|
27
|
+
]
|
28
|
+
end
|
29
|
+
|
30
|
+
def register_hooks
|
31
|
+
after 'deploy:new_release_path', 'copy:create_release'
|
32
|
+
before 'deploy:check', 'copy:check'
|
33
|
+
before 'deploy:set_current_revision', 'copy:set_current_revision'
|
34
|
+
end
|
35
|
+
|
36
|
+
def define_tasks
|
37
|
+
eval_rakefile File.expand_path('../copy.rake', __FILE__)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Archive filename as singleton
|
41
|
+
# Note: if the archive filename doesn't already exist it will be generated
|
42
|
+
#
|
43
|
+
# @return [String]
|
44
|
+
def archive_filename
|
45
|
+
@archive_filename ||= Dir::Tmpname.make_tmpname [application + '_', '.tar.gz'], nil
|
46
|
+
end
|
47
|
+
|
48
|
+
# Local temporary directory path as singleton
|
49
|
+
# Note: if the directory doesn't already exist it will be created
|
50
|
+
#
|
51
|
+
# @return [String]
|
52
|
+
def local_tmp_dir
|
53
|
+
@local_tmp_dir ||= Dir.mktmpdir
|
54
|
+
end
|
55
|
+
|
56
|
+
# Archive path in a local temporary directory
|
57
|
+
#
|
58
|
+
# @return [String]
|
59
|
+
def local_exclude_path
|
60
|
+
File.join local_tmp_dir, 'exclude.txt'
|
61
|
+
end
|
62
|
+
|
63
|
+
# Archive path in a local temporary directory
|
64
|
+
#
|
65
|
+
# @return [String]
|
66
|
+
def local_archive_path
|
67
|
+
File.join local_tmp_dir, archive_filename
|
68
|
+
end
|
69
|
+
|
70
|
+
# Remote temporary directory path
|
71
|
+
#
|
72
|
+
# @return [String]
|
73
|
+
def remote_tmp_dir
|
74
|
+
File.join fetch(:tmp_dir), application
|
75
|
+
end
|
76
|
+
|
77
|
+
# Archive path in a remote temporary directory
|
78
|
+
#
|
79
|
+
# @return [String]
|
80
|
+
def remote_archive_path
|
81
|
+
File.join remote_tmp_dir, archive_filename
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/dkdeploy/tasks/db.rake
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'dkdeploy/constants'
|
2
2
|
require 'dkdeploy/helpers/common'
|
3
3
|
require 'dkdeploy/helpers/db'
|
4
|
-
require 'dkdeploy/interaction_handler/
|
4
|
+
require 'dkdeploy/interaction_handler/mysql'
|
5
5
|
require 'digest/md5'
|
6
6
|
require 'yaml'
|
7
7
|
|
@@ -11,8 +11,7 @@ include Dkdeploy::Helpers::DB
|
|
11
11
|
include Capistrano::DSL
|
12
12
|
|
13
13
|
namespace :db do
|
14
|
-
task :
|
15
|
-
FileUtils.mkdir_p 'temp'
|
14
|
+
task read_db_settings: 'utils:create_local_temp_directory' do
|
16
15
|
on release_roles :app do
|
17
16
|
unless test("[ -f #{remote_database_config_path} ]")
|
18
17
|
error I18n.t('errors.database_config_file_missing', scope: :dkdeploy)
|
@@ -52,7 +51,7 @@ namespace :db do
|
|
52
51
|
execute :mysql,
|
53
52
|
'-u', fetch(:db_username),
|
54
53
|
'-p', '-h', fetch(:db_host), '-P', fetch(:db_port), '-e', 'exit',
|
55
|
-
interaction_handler: Dkdeploy::InteractionHandler::
|
54
|
+
interaction_handler: Dkdeploy::InteractionHandler::MySql.new(fetch(:db_password))
|
56
55
|
rescue SSHKit::Command::Failed
|
57
56
|
error I18n.t('errors.connection_failed', scope: :dkdeploy)
|
58
57
|
exit 1
|
@@ -93,7 +92,7 @@ namespace :db do
|
|
93
92
|
'-p',
|
94
93
|
'-h', db_settings.fetch('host'), '-P', db_settings.fetch('port'), db_settings.fetch('name'),
|
95
94
|
'-e', "'source #{remote_file_name}'",
|
96
|
-
interaction_handler: Dkdeploy::InteractionHandler::
|
95
|
+
interaction_handler: Dkdeploy::InteractionHandler::MySql.new(db_settings.fetch('password'))
|
97
96
|
ensure
|
98
97
|
execute :rm, '-f', remote_zipped_file_name
|
99
98
|
execute :rm, '-f', remote_file_name
|
@@ -102,12 +101,10 @@ namespace :db do
|
|
102
101
|
end
|
103
102
|
|
104
103
|
desc 'Dump complete database without cache table content to local temp folder'
|
105
|
-
task download: [
|
104
|
+
task download: %i[download_structure download_content]
|
106
105
|
|
107
106
|
desc 'Dumps complete database structure without content'
|
108
|
-
task :
|
109
|
-
FileUtils.mkdir_p 'temp'
|
110
|
-
|
107
|
+
task download_structure: 'utils:create_local_temp_directory' do
|
111
108
|
dump_file = db_dump_file_structure
|
112
109
|
remote_dump_file = File.join(fetch(:deploy_to), dump_file)
|
113
110
|
remote_zipped_dump_file = "#{remote_dump_file}.gz"
|
@@ -118,13 +115,13 @@ namespace :db do
|
|
118
115
|
execute :rm, '-f', remote_dump_file
|
119
116
|
execute :rm, '-f', remote_zipped_dump_file
|
120
117
|
execute :mysqldump,
|
121
|
-
'--no-data', '--skip-set-charset',
|
118
|
+
'--no-data', '--skip-set-charset',
|
122
119
|
"--default-character-set=#{db_settings.fetch('charset')}",
|
123
120
|
'-u', db_settings.fetch('username'),
|
124
121
|
'-p',
|
125
122
|
'-h', db_settings.fetch('host'), '-P', db_settings.fetch('port'), db_settings.fetch('name'),
|
126
123
|
'>', remote_dump_file,
|
127
|
-
interaction_handler: Dkdeploy::InteractionHandler::
|
124
|
+
interaction_handler: Dkdeploy::InteractionHandler::MySql.new(db_settings.fetch('password'))
|
128
125
|
execute :gzip, remote_dump_file
|
129
126
|
download! remote_zipped_dump_file, 'temp', via: :scp
|
130
127
|
ensure
|
@@ -135,9 +132,7 @@ namespace :db do
|
|
135
132
|
end
|
136
133
|
|
137
134
|
desc 'Dump complete database content without cache tables and structure to local temp folder'
|
138
|
-
task :
|
139
|
-
FileUtils.mkdir_p 'temp'
|
140
|
-
|
135
|
+
task download_content: 'utils:create_local_temp_directory' do
|
141
136
|
dump_file = db_dump_file_content
|
142
137
|
remote_dump_file = File.join(fetch(:deploy_to), dump_file)
|
143
138
|
remote_zipped_dump_file = "#{remote_dump_file}.gz"
|
@@ -155,12 +150,11 @@ namespace :db do
|
|
155
150
|
execute :mysqldump,
|
156
151
|
"--default-character-set=#{db_settings.fetch('charset')}",
|
157
152
|
'--skip-set-charset',
|
158
|
-
'--no-tablespaces',
|
159
153
|
'-u', db_settings.fetch('username'),
|
160
154
|
'-p',
|
161
155
|
'-h', db_settings.fetch('host'), '-P', db_settings.fetch('port'), ignore_tables_command_line, db_settings.fetch('name'),
|
162
156
|
'>', remote_dump_file,
|
163
|
-
interaction_handler: Dkdeploy::InteractionHandler::
|
157
|
+
interaction_handler: Dkdeploy::InteractionHandler::MySql.new(db_settings.fetch('password'))
|
164
158
|
execute :gzip, remote_dump_file
|
165
159
|
download! remote_zipped_dump_file, 'temp', via: :scp
|
166
160
|
ensure
|
@@ -171,11 +165,9 @@ namespace :db do
|
|
171
165
|
end
|
172
166
|
|
173
167
|
desc 'Dump content of a database table to local temp folder'
|
174
|
-
task :dump_table, :table_name do |_, args|
|
168
|
+
task :dump_table, [:table_name] => ['utils:create_local_temp_directory'] do |_, args|
|
175
169
|
table_name = ask_variable(args, :table_name, 'questions.database.table_name')
|
176
170
|
|
177
|
-
FileUtils.mkdir_p 'temp'
|
178
|
-
|
179
171
|
dump_file = db_dump_file table_name
|
180
172
|
zipped_dump_file = File.join('temp', "#{dump_file}.gz")
|
181
173
|
remote_dump_file = File.join(deploy_to, dump_file)
|
@@ -187,13 +179,13 @@ namespace :db do
|
|
187
179
|
execute :rm, '-f', remote_dump_file
|
188
180
|
execute :rm, '-f', remote_zipped_dump_file
|
189
181
|
execute :mysqldump,
|
190
|
-
'--no-data', '--skip-set-charset',
|
182
|
+
'--no-data', '--skip-set-charset',
|
191
183
|
"--default-character-set=#{db_settings.fetch('charset')}",
|
192
184
|
'-u', db_settings.fetch('username'),
|
193
185
|
'-p',
|
194
186
|
'-h', db_settings.fetch('host'), '-P', db_settings.fetch('port'), db_settings.fetch('name'), table_name,
|
195
187
|
'>', remote_dump_file,
|
196
|
-
interaction_handler: Dkdeploy::InteractionHandler::
|
188
|
+
interaction_handler: Dkdeploy::InteractionHandler::MySql.new(db_settings.fetch('password'))
|
197
189
|
execute :gzip, remote_dump_file
|
198
190
|
download! remote_zipped_dump_file, zipped_dump_file, via: :scp
|
199
191
|
ensure
|
@@ -222,7 +214,7 @@ namespace :db do
|
|
222
214
|
execute :rm, '-f', remote_file_name
|
223
215
|
execute :rm, '-f', remote_zipped_file
|
224
216
|
execute :mysqldump,
|
225
|
-
'--no-data', '--skip-set-charset',
|
217
|
+
'--no-data', '--skip-set-charset',
|
226
218
|
'--no-create-info', '--skip-comments',
|
227
219
|
'--skip-extended-insert', '--skip-set-charset',
|
228
220
|
"--default-character-set=#{db_settings.fetch('charset')}",
|
@@ -231,7 +223,7 @@ namespace :db do
|
|
231
223
|
'-h', db_settings.fetch('host'), '-P', db_settings.fetch('port'),
|
232
224
|
db_settings.fetch('name'), table_names.join(' '),
|
233
225
|
'>', remote_file_name,
|
234
|
-
interaction_handler: Dkdeploy::InteractionHandler::
|
226
|
+
interaction_handler: Dkdeploy::InteractionHandler::MySql.new(db_settings.fetch('password'))
|
235
227
|
execute :gzip, remote_file_name
|
236
228
|
download! remote_zipped_file, local_zipped_file, via: :scp
|
237
229
|
ensure
|
@@ -264,7 +256,7 @@ namespace :db do
|
|
264
256
|
'-p',
|
265
257
|
'-h', db_settings.fetch('host'), '-P', db_settings.fetch('port'), db_settings.fetch('name'),
|
266
258
|
'-e', "'source #{remote_default_content_file}'",
|
267
|
-
interaction_handler: Dkdeploy::InteractionHandler::
|
259
|
+
interaction_handler: Dkdeploy::InteractionHandler::MySql.new(db_settings.fetch('password'))
|
268
260
|
ensure
|
269
261
|
execute :rm, '-f', remote_default_content_file
|
270
262
|
execute :rm, '-f', remote_zipped_default_content_file
|
@@ -290,7 +282,7 @@ namespace :db do
|
|
290
282
|
'-u', db_settings.fetch('username'), '-p',
|
291
283
|
'-h', db_settings.fetch('host'), '-P', db_settings.fetch('port'), db_settings.fetch('name'),
|
292
284
|
'-e', "'source #{remote_default_structure_file}'",
|
293
|
-
interaction_handler: Dkdeploy::InteractionHandler::
|
285
|
+
interaction_handler: Dkdeploy::InteractionHandler::MySql.new(db_settings.fetch('password'))
|
294
286
|
ensure
|
295
287
|
execute :rm, '-f', remote_default_structure_file
|
296
288
|
execute :rm, '-f', remote_zipped_default_structure_file
|
@@ -321,13 +313,13 @@ namespace :db do
|
|
321
313
|
"--default-character-set=#{db_settings.fetch('charset')}",
|
322
314
|
'--no-create-info', '--skip-comments',
|
323
315
|
'--skip-extended-insert', '--skip-set-charset',
|
324
|
-
'--complete-insert',
|
316
|
+
'--complete-insert',
|
325
317
|
'-u', db_settings.fetch('username'),
|
326
318
|
'-p',
|
327
319
|
'-h', db_settings.fetch('host'), '-P', db_settings.fetch('port'),
|
328
320
|
db_settings.fetch('name'), table_names,
|
329
321
|
'>', remote_file_name,
|
330
|
-
interaction_handler: Dkdeploy::InteractionHandler::
|
322
|
+
interaction_handler: Dkdeploy::InteractionHandler::MySql.new(db_settings.fetch('password'))
|
331
323
|
execute :gzip, remote_file_name
|
332
324
|
download! remote_zipped_file, local_zipped_file, via: :scp
|
333
325
|
ensure
|
@@ -398,7 +390,7 @@ namespace :db do
|
|
398
390
|
'-p',
|
399
391
|
'-h', db_settings.fetch('host'), '-P', db_settings.fetch('port'), db_settings.fetch('name'),
|
400
392
|
'-e', "'source #{remote_dump_file}'",
|
401
|
-
interaction_handler: Dkdeploy::InteractionHandler::
|
393
|
+
interaction_handler: Dkdeploy::InteractionHandler::MySql.new(db_settings.fetch('password'))
|
402
394
|
end
|
403
395
|
rescue SSHKit::Command::Failed => exception
|
404
396
|
run_locally do
|
@@ -5,16 +5,6 @@ include Dkdeploy::DSL
|
|
5
5
|
include Dkdeploy::RollbackManager
|
6
6
|
|
7
7
|
namespace :deploy do
|
8
|
-
desc 'Generate the new release path name'
|
9
|
-
task :new_release_path do
|
10
|
-
jenkins_suffix = ''
|
11
|
-
# Add jenkins build name and number to release path
|
12
|
-
if ENV['BUILD_TAG']
|
13
|
-
jenkins_suffix = "-#{ENV['JOB_NAME']}-#{ENV['BUILD_NUMBER']}"
|
14
|
-
end
|
15
|
-
set_release_path releases_path.join(Time.now.utc.strftime('%Y-%m-%d-%H-%M-%S') + jenkins_suffix)
|
16
|
-
end
|
17
|
-
|
18
8
|
desc 'Handle deployment errors'
|
19
9
|
task :failed do
|
20
10
|
# Rollback tasks. Reverse sorting for rollback
|
@@ -58,7 +48,7 @@ namespace :deploy do
|
|
58
48
|
on release_roles(:all) do
|
59
49
|
begin
|
60
50
|
rollback_archives = capture(:ls, '-x', deploy_path.join('rolled-back-release-*.tar.gz')).split
|
61
|
-
rescue
|
51
|
+
rescue SSHKit::StandardError
|
62
52
|
rollback_archives = []
|
63
53
|
end
|
64
54
|
|
@@ -6,7 +6,7 @@ namespace :deploy do
|
|
6
6
|
desc "Check directories to be linked exist in shared using the given hash 'enhanced_linked_dirs'"
|
7
7
|
task :linked_dirs do
|
8
8
|
next unless any? :enhanced_linked_dirs
|
9
|
-
fetch(:enhanced_linked_dirs).
|
9
|
+
fetch(:enhanced_linked_dirs).each_key do |source|
|
10
10
|
on release_roles :all do
|
11
11
|
execute :mkdir, '-pv', shared_path.join(source)
|
12
12
|
end
|
@@ -16,7 +16,7 @@ namespace :deploy do
|
|
16
16
|
desc "Check directories of files to be linked exist in shared using the given hash 'enhanced_linked_files'"
|
17
17
|
task :make_linked_dirs do
|
18
18
|
next unless any? :enhanced_linked_files
|
19
|
-
fetch(:enhanced_linked_files).
|
19
|
+
fetch(:enhanced_linked_files).each_value do |target|
|
20
20
|
on release_roles :all do
|
21
21
|
execute :mkdir, '-pv', shared_path.join(target).dirname
|
22
22
|
end
|
@@ -26,7 +26,7 @@ namespace :deploy do
|
|
26
26
|
desc "Check files to be linked exist in shared using the given hash 'enhanced_linked_files'"
|
27
27
|
task :linked_files do
|
28
28
|
next unless any? :enhanced_linked_files
|
29
|
-
fetch(:enhanced_linked_files).
|
29
|
+
fetch(:enhanced_linked_files).each_key do |source|
|
30
30
|
on release_roles :all do |host|
|
31
31
|
unless test "[ -f #{shared_path.join source} ]"
|
32
32
|
error t(:linked_file_does_not_exist, file: source, host: host)
|
@@ -3,16 +3,15 @@ require 'dkdeploy/i18n'
|
|
3
3
|
require 'dkdeploy/helpers/file_system'
|
4
4
|
|
5
5
|
include Capistrano::DSL
|
6
|
-
include SSHKit::DSL
|
7
6
|
include Dkdeploy::Helpers::FileSystem
|
8
7
|
|
9
8
|
namespace :file_access do
|
10
9
|
desc 'Set standard defined owner and group on the shared and release path'
|
11
|
-
task set_owner_group: [
|
10
|
+
task set_owner_group: %i[set_owner_group_of_shared_path set_owner_group_of_release_path]
|
12
11
|
|
13
12
|
desc 'Set standard defined owner and group on the shared path'
|
14
13
|
task :set_owner_group_of_shared_path do
|
15
|
-
on release_roles :
|
14
|
+
on release_roles :all do
|
16
15
|
paths = merge_paths_with_resolved_symlinks self, shared_path
|
17
16
|
execute :chown, "#{fetch(:default_file_access_owner_of_shared_path)}:#{fetch(:default_file_access_group_of_shared_path)}", paths
|
18
17
|
end
|
@@ -20,18 +19,18 @@ namespace :file_access do
|
|
20
19
|
|
21
20
|
desc 'Set recursively standard defined owner and group on the release path'
|
22
21
|
task :set_owner_group_of_release_path do
|
23
|
-
on release_roles :
|
22
|
+
on release_roles :all do
|
24
23
|
paths = merge_paths_with_resolved_symlinks self, release_path
|
25
24
|
execute :chown, '-R', "#{fetch(:default_file_access_owner_of_release_path)}:#{fetch(:default_file_access_group_of_release_path)}", paths
|
26
25
|
end
|
27
26
|
end
|
28
27
|
|
29
28
|
desc 'Set standard defined file permissions on the shared and release path'
|
30
|
-
task set_permissions: [
|
29
|
+
task set_permissions: %i[set_permissions_of_shared_path set_permissions_of_release_path]
|
31
30
|
|
32
31
|
desc 'Set standard defined file permissions on the shared path'
|
33
32
|
task :set_permissions_of_shared_path do
|
34
|
-
on release_roles :
|
33
|
+
on release_roles :all do
|
35
34
|
paths = merge_paths_with_resolved_symlinks self, shared_path
|
36
35
|
execute :chmod, fetch(:default_file_access_mode_of_shared_path), paths
|
37
36
|
end
|
@@ -39,7 +38,7 @@ namespace :file_access do
|
|
39
38
|
|
40
39
|
desc 'Set recursively standard defined file permissions on the release path'
|
41
40
|
task :set_permissions_of_release_path do
|
42
|
-
on release_roles :
|
41
|
+
on release_roles :all do
|
43
42
|
paths = merge_paths_with_resolved_symlinks self, release_path
|
44
43
|
execute :chmod, '-R', fetch(:default_file_access_mode_of_release_path), paths
|
45
44
|
end
|
@@ -49,7 +48,7 @@ namespace :file_access do
|
|
49
48
|
task :set_custom_access do
|
50
49
|
fetch(:custom_file_access, {}).each do |role, paths_hash|
|
51
50
|
on release_roles role do |host|
|
52
|
-
release_or_shared_paths = paths_hash.select { |k, _| [
|
51
|
+
release_or_shared_paths = paths_hash.select { |k, _| %i[release_path shared_path].include? k } # allow only :release_path and :shared_path entries
|
53
52
|
release_or_shared_paths.each do |release_or_shared_path, paths|
|
54
53
|
paths.each do |path, access_properties|
|
55
54
|
path = map_path_in_release_or_shared_path(release_or_shared_path, path.to_s) # build absolute path
|
@@ -72,7 +71,7 @@ namespace :file_access do
|
|
72
71
|
|
73
72
|
fetch(:custom_file_access, {}).each do |role, paths_hash|
|
74
73
|
on release_roles role do |host|
|
75
|
-
release_or_shared_paths = paths_hash.select { |k, _| [
|
74
|
+
release_or_shared_paths = paths_hash.select { |k, _| %i[release_path shared_path].include? k } # allow only :release_path and :shared_path entries
|
76
75
|
release_or_shared_paths.each do |release_or_shared_path, paths|
|
77
76
|
paths.each do |path, access_properties|
|
78
77
|
unless list_of_selected_paths.include?(path)
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'dkdeploy/constants'
|
2
|
+
require 'dkdeploy/helpers/common'
|
3
|
+
require 'dkdeploy/helpers/mysql'
|
4
|
+
|
5
|
+
include Dkdeploy::Constants
|
6
|
+
include Dkdeploy::Helpers::Common
|
7
|
+
include Dkdeploy::Helpers::MySQL
|
8
|
+
include Capistrano::DSL
|
9
|
+
|
10
|
+
namespace :mysql do
|
11
|
+
desc 'Clear slow log file'
|
12
|
+
task :clear_slow_log do
|
13
|
+
mysql_slow_log = fetch(:mysql_slow_log, '')
|
14
|
+
on roles :db do |server|
|
15
|
+
next unless slow_log_exists? mysql_slow_log
|
16
|
+
execute :echo, '', '>', mysql_slow_log
|
17
|
+
info I18n.t('tasks.mysql.clear_slow_log', file: mysql_slow_log, host: server, scope: :dkdeploy)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'Download slow log file to temp/'
|
22
|
+
task download_slow_log: 'utils:create_local_temp_directory' do
|
23
|
+
mysql_slow_log = fetch(:mysql_slow_log, '')
|
24
|
+
on roles :db do |server|
|
25
|
+
next unless slow_log_exists? mysql_slow_log
|
26
|
+
local_filename = File.join(local_dump_path, "#{File.basename(mysql_slow_log, '.*')}.#{fetch(:stage)}.#{server.hostname}#{File.extname(mysql_slow_log)}")
|
27
|
+
info I18n.t('file.download', file: mysql_slow_log, target: local_filename, host: server)
|
28
|
+
download! mysql_slow_log, local_filename, via: :scp
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
desc 'Download slow log file to temp'
|
33
|
+
task analyze_download_slow_log: 'utils:create_local_temp_directory' do
|
34
|
+
mysql_slow_log = fetch(:mysql_slow_log, '')
|
35
|
+
on roles :db do |server|
|
36
|
+
next unless slow_log_exists? mysql_slow_log
|
37
|
+
analyze_filename = "mysql_slow_log_analyze.#{fetch(:stage)}.#{server.hostname}.log"
|
38
|
+
remote_filename = File.join(deploy_path, analyze_filename)
|
39
|
+
local_filename = File.join(local_dump_path, analyze_filename)
|
40
|
+
# delete file, if exist
|
41
|
+
execute :rm, '-f', remote_filename
|
42
|
+
info I18n.t('tasks.mysql.analyze_slow_log', host: server, scope: :dkdeploy)
|
43
|
+
execute :mysqldumpslow, '-s', 't', mysql_slow_log, '>', remote_filename
|
44
|
+
info I18n.t('file.download', file: remote_filename, target: local_filename, host: server)
|
45
|
+
download! remote_filename, local_filename, via: :scp
|
46
|
+
# delete file, if exist
|
47
|
+
execute :rm, '-f', remote_filename
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -2,7 +2,6 @@ require 'capistrano/i18n'
|
|
2
2
|
require 'dkdeploy/i18n'
|
3
3
|
|
4
4
|
include Capistrano::DSL
|
5
|
-
include SSHKit::DSL
|
6
5
|
|
7
6
|
namespace :utils do
|
8
7
|
desc 'Get current webroot path in releases'
|
@@ -88,7 +87,7 @@ namespace :utils do
|
|
88
87
|
# Append '/' to source directory
|
89
88
|
rsync_path = File.join(rsync_path, '')
|
90
89
|
|
91
|
-
rsync_command = %w
|
90
|
+
rsync_command = %w[--verbose --recursive --perms --times --perms --perms --compress --force --cvs-exclude]
|
92
91
|
|
93
92
|
# Build exclude parameter
|
94
93
|
rsync_exclude.each do |exclude|
|
@@ -138,4 +137,9 @@ namespace :utils do
|
|
138
137
|
end
|
139
138
|
end
|
140
139
|
end
|
140
|
+
|
141
|
+
desc 'Create local temporary directory'
|
142
|
+
task :create_local_temp_directory do
|
143
|
+
run_locally { execute :mkdir, '-p', local_dump_path }
|
144
|
+
end
|
141
145
|
end
|