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.
Files changed (51) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +9 -0
  3. data/.travis.yml +13 -0
  4. data/CHANGELOG.md +38 -0
  5. data/CONTRIBUTORS.md +2 -0
  6. data/LICENSE +1 -1
  7. data/README.md +8 -5
  8. data/Vagrantfile +3 -10
  9. data/assets/dkdeploy-logo.png +0 -0
  10. data/config/vm/cookbooks/dkdeploy-core/recipes/default.rb +13 -1
  11. data/config/vm/cookbooks/dkdeploy-core/templates/my_extra_settings.erb +6 -0
  12. data/dkdeploy-core.gemspec +11 -12
  13. data/features/assets.feature +24 -26
  14. data/features/db.feature +4 -0
  15. data/features/mysql.feature +27 -0
  16. data/features/support/env.rb +1 -1
  17. data/lib/capistrano/dkdeploy/core.rb +11 -22
  18. data/lib/dkdeploy/constants.rb +5 -73
  19. data/lib/dkdeploy/core/version.rb +2 -2
  20. data/lib/dkdeploy/dsl.rb +1 -1
  21. data/lib/dkdeploy/helpers/assets.rb +0 -1
  22. data/lib/dkdeploy/helpers/db.rb +1 -1
  23. data/lib/dkdeploy/helpers/mysql.rb +17 -0
  24. data/lib/dkdeploy/i18n.rb +6 -0
  25. data/lib/dkdeploy/interaction_handler/mysql.rb +38 -0
  26. data/lib/dkdeploy/interaction_handler/password.rb +3 -2
  27. data/lib/dkdeploy/scm/copy.rake +76 -0
  28. data/lib/dkdeploy/scm/copy.rb +85 -0
  29. data/lib/dkdeploy/tasks/apache.rake +0 -1
  30. data/lib/dkdeploy/tasks/assets.rake +0 -1
  31. data/lib/dkdeploy/tasks/bower.rake +0 -1
  32. data/lib/dkdeploy/tasks/db.rake +20 -28
  33. data/lib/dkdeploy/tasks/deploy.rake +1 -11
  34. data/lib/dkdeploy/tasks/enhanced_symlinks.rake +3 -3
  35. data/lib/dkdeploy/tasks/file_access.rake +8 -9
  36. data/lib/dkdeploy/tasks/maintenance.rake +0 -1
  37. data/lib/dkdeploy/tasks/mysql.rake +50 -0
  38. data/lib/dkdeploy/tasks/project_version.rake +0 -1
  39. data/lib/dkdeploy/tasks/utils.rake +6 -2
  40. data/spec/fixtures/application/Gemfile +1 -1
  41. data/spec/fixtures/application/config/deploy/dev.rb +6 -3
  42. data/spec/fixtures/application/config/deploy.rb +42 -5
  43. data/spec/fixtures/application/config/preseed/default_content.sql.gz +0 -0
  44. data/spec/fixtures/application/config/preseed/download.tar.gz +0 -0
  45. data/spec/fixtures/capistrano/configuration/add_output_after_create_symlink.rb +1 -2
  46. data/spec/fixtures/capistrano/configuration/custom_compass_sources.rb +2 -2
  47. metadata +41 -55
  48. data/lib/dkdeploy/copy.rb +0 -121
  49. data/lib/dkdeploy/tasks/copy.rake +0 -26
  50. data/spec/fixtures/application/config/preseed/fileadmin.tar.gz +0 -0
  51. 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
@@ -3,7 +3,6 @@ require 'capistrano/i18n'
3
3
  require 'dkdeploy/i18n'
4
4
 
5
5
  include Capistrano::DSL
6
- include SSHKit::DSL
7
6
 
8
7
  namespace :apache do
9
8
  desc 'Render .htaccess to web root from erb template(s)'
@@ -6,7 +6,6 @@ require 'dkdeploy/interaction_handler/password'
6
6
  require 'dkdeploy/constants'
7
7
 
8
8
  include Capistrano::DSL
9
- include SSHKit::DSL
10
9
  include Dkdeploy::Helpers::Common
11
10
  include Dkdeploy::Helpers::Assets
12
11
  include Dkdeploy::Constants
@@ -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 :bower do
8
7
  desc 'Runs given Bower command in given path'
@@ -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/password'
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 :read_db_settings do
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::Password.new(fetch(:db_password))
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::Password.new(db_settings.fetch('password'))
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: [:download_structure, :download_content]
104
+ task download: %i[download_structure download_content]
106
105
 
107
106
  desc 'Dumps complete database structure without content'
108
- task :download_structure do
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', '--no-tablespaces',
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::Password.new(db_settings.fetch('password'))
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 :download_content do
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::Password.new(db_settings.fetch('password'))
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', '--no-tablespaces',
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::Password.new(db_settings.fetch('password'))
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', '--no-tablespaces',
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::Password.new(db_settings.fetch('password'))
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::Password.new(db_settings.fetch('password'))
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::Password.new(db_settings.fetch('password'))
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', '--no-tablespaces',
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::Password.new(db_settings.fetch('password'))
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::Password.new(db_settings.fetch('password'))
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).each do |source, _|
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).each do |_, target|
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).each do |source, _|
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: [:set_owner_group_of_shared_path, :set_owner_group_of_release_path]
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 :app do
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 :app do
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: [:set_permissions_of_shared_path, :set_permissions_of_release_path]
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 :app do
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 :app do
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, _| [:release_path, :shared_path].include? k } # allow only :release_path and :shared_path entries
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, _| [:release_path, :shared_path].include? k } # allow only :release_path and :shared_path entries
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)
@@ -5,7 +5,6 @@ require 'sshkit/dsl'
5
5
  require 'capistrano/dsl'
6
6
 
7
7
  include Capistrano::DSL
8
- include SSHKit::DSL
9
8
  include Dkdeploy::RollbackManager
10
9
 
11
10
  namespace :maintenance do
@@ -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
@@ -3,7 +3,6 @@ require 'dkdeploy/i18n'
3
3
  require 'dkdeploy/constants'
4
4
 
5
5
  include Capistrano::DSL
6
- include SSHKit::DSL
7
6
 
8
7
  namespace :project_version do
9
8
  desc 'Update Version file on server'
@@ -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(--verbose --recursive --perms --times --perms --perms --compress --force --cvs-exclude)
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
@@ -8,4 +8,4 @@ gem 'compass', '~> 1.0.3'
8
8
  # for debugging only
9
9
  gem 'pry', '~> 0.10.0'
10
10
 
11
- gem 'bundler', '~> 1.12.5'
11
+ gem 'bundler'