capistrano-ops 0.2.14 → 1.0.0

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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +121 -29
  3. data/lib/capistrano/ops/backup/helper.rb +56 -0
  4. data/lib/capistrano/ops/{capistrano/v3/tasks/backup → backup/tasks}/database/create.rake +1 -2
  5. data/lib/capistrano/ops/{capistrano/v3/tasks/backup → backup/tasks}/database/pull.rake +1 -2
  6. data/lib/capistrano/ops/{capistrano/v3/tasks/backup → backup/tasks}/storage/create.rake +1 -2
  7. data/lib/capistrano/ops/{capistrano/v3/tasks/backup → backup/tasks}/storage/pull.rake +1 -2
  8. data/lib/capistrano/ops/backup.rb +14 -4
  9. data/lib/capistrano/ops/capistrano.rb +8 -13
  10. data/lib/capistrano/ops/figaro_yml/helpers.rb +184 -0
  11. data/lib/capistrano/ops/figaro_yml/paths.rb +19 -0
  12. data/lib/capistrano/ops/figaro_yml/tasks/backup.rake +26 -0
  13. data/lib/capistrano/ops/figaro_yml/tasks/check.rake +12 -0
  14. data/lib/capistrano/ops/figaro_yml/tasks/check_config_present.rake +12 -0
  15. data/lib/capistrano/ops/figaro_yml/tasks/check_figaro_file_exists.rake +12 -0
  16. data/lib/capistrano/ops/figaro_yml/tasks/check_git_tracking.rake +12 -0
  17. data/lib/capistrano/ops/{capistrano/v3/tasks/figaro_yml → figaro_yml/tasks}/compare.rake +10 -19
  18. data/lib/capistrano/ops/figaro_yml/tasks/create_local.rake +27 -0
  19. data/lib/capistrano/ops/figaro_yml/tasks/figaro_yml_symlink.rake +10 -0
  20. data/lib/capistrano/ops/figaro_yml/tasks/get.rake +45 -0
  21. data/lib/capistrano/ops/figaro_yml/tasks/get_stage.rake +15 -0
  22. data/lib/capistrano/ops/figaro_yml/tasks/load.rake +10 -0
  23. data/lib/capistrano/ops/figaro_yml/tasks/rollback.rake +22 -0
  24. data/lib/capistrano/ops/figaro_yml/tasks/setup.rake +16 -0
  25. data/lib/capistrano/ops/{capistrano/v3/tasks/figaro_yml → figaro_yml/tasks}/sort_local.rake +2 -4
  26. data/lib/capistrano/ops/figaro_yml.rb +29 -0
  27. data/lib/capistrano/ops/helper.rb +14 -0
  28. data/lib/capistrano/ops/invoke/tasks/invoke.rake +25 -0
  29. data/lib/capistrano/ops/invoke.rb +3 -0
  30. data/lib/capistrano/ops/logrotate/helpers.rb +50 -0
  31. data/lib/capistrano/ops/logrotate/paths.rb +47 -0
  32. data/lib/capistrano/ops/{capistrano/v3/tasks/logrotate → logrotate/tasks}/check.rake +3 -5
  33. data/lib/capistrano/ops/{capistrano/v3/tasks/logrotate → logrotate/tasks}/disable.rake +2 -5
  34. data/lib/capistrano/ops/logrotate/tasks/enable.rake +28 -0
  35. data/lib/capistrano/ops/logrotate/tasks/load.rake +10 -0
  36. data/lib/capistrano/ops/logrotate.rb +19 -0
  37. data/lib/capistrano/ops/logs/helpers.rb +16 -0
  38. data/lib/capistrano/ops/logs/paths.rb +23 -0
  39. data/lib/capistrano/ops/logs/tasks/load.rake +9 -0
  40. data/lib/capistrano/ops/logs/tasks/rails.rake +18 -0
  41. data/lib/capistrano/ops/logs/tasks/sidekiq.rake +42 -0
  42. data/lib/capistrano/ops/logs.rb +18 -0
  43. data/lib/capistrano/ops/{backup → rails/lib/backup}/s3.rb +1 -1
  44. data/lib/capistrano/ops/rails/lib/backup.rb +6 -0
  45. data/lib/capistrano/ops/rails/lib/notification.rb +9 -0
  46. data/lib/capistrano/ops/rails/lib/railtie.rb +17 -0
  47. data/lib/capistrano/ops/{tasks → rails/lib/tasks}/pg/postgres_helper.rb +1 -1
  48. data/lib/capistrano/ops/version.rb +1 -1
  49. data/lib/capistrano/ops/{capistrano/v3/tasks/whenever.rake → whenever/tasks/show_crontab.rake} +1 -3
  50. data/lib/capistrano/ops/whenever.rb +17 -0
  51. data/lib/capistrano/ops/wkhtmltopdf/helpers.rb +50 -0
  52. data/lib/capistrano/ops/wkhtmltopdf/tasks/setup.rake +17 -0
  53. data/lib/capistrano/ops/wkhtmltopdf.rb +17 -1
  54. data/lib/capistrano/ops.rb +4 -3
  55. metadata +60 -36
  56. data/lib/capistrano/ops/capistrano/tasks/wkhtmltopdf.rake +0 -48
  57. data/lib/capistrano/ops/capistrano/v3/tasks/backup/backup_helper.rb +0 -50
  58. data/lib/capistrano/ops/capistrano/v3/tasks/figaro_yml/figaro_yaml_helper.rb +0 -74
  59. data/lib/capistrano/ops/capistrano/v3/tasks/figaro_yml/get.rake +0 -68
  60. data/lib/capistrano/ops/capistrano/v3/tasks/figaro_yml/get_stage.rake +0 -13
  61. data/lib/capistrano/ops/capistrano/v3/tasks/figaro_yml.rb +0 -3
  62. data/lib/capistrano/ops/capistrano/v3/tasks/invoke.rake +0 -23
  63. data/lib/capistrano/ops/capistrano/v3/tasks/logrotate/enable.rake +0 -24
  64. data/lib/capistrano/ops/capistrano/v3/tasks/logrotate/logrotate_helper.rb +0 -68
  65. data/lib/capistrano/ops/capistrano/v3/tasks/logs/rails.rake +0 -16
  66. data/lib/capistrano/ops/notification.rb +0 -9
  67. data/lib/capistrano/ops/railtie.rb +0 -15
  68. /data/lib/capistrano/ops/{capistrano/v3/tasks/logrotate → logrotate/tasks}/templates/logrotate.conf.erb +0 -0
  69. /data/lib/capistrano/ops/{capistrano/v3/tasks/logrotate → logrotate/tasks}/templates/schedule.rb.erb +0 -0
  70. /data/lib/capistrano/ops/{backup → rails/lib/backup}/api.rb +0 -0
  71. /data/lib/capistrano/ops/{backup → rails/lib/backup}/s3_helper.rb +0 -0
  72. /data/lib/capistrano/ops/{notification → rails/lib/notification}/api.rb +0 -0
  73. /data/lib/capistrano/ops/{notification → rails/lib/notification}/slack.rb +0 -0
  74. /data/lib/capistrano/ops/{notification → rails/lib/notification}/webhook.rb +0 -0
  75. /data/lib/capistrano/ops/{tasks → rails/lib/tasks}/pg/dump.rake +0 -0
  76. /data/lib/capistrano/ops/{tasks → rails/lib/tasks}/pg/remove_old_dumps.rake +0 -0
  77. /data/lib/capistrano/ops/{tasks → rails/lib/tasks}/storage/backup.rake +0 -0
  78. /data/lib/capistrano/ops/{tasks → rails/lib/tasks}/storage/remove_old_backups.rake +0 -0
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+
5
+ module Capistrano
6
+ module Ops
7
+ module FigaroYml
8
+ module Paths
9
+ def figaro_yml_local_path
10
+ Pathname.new fetch(:figaro_yml_local_path)
11
+ end
12
+
13
+ def figaro_yml_remote_path
14
+ shared_path.join fetch(:figaro_yml_remote_path)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :figaro_yml do
4
+ include Capistrano::Ops::FigaroYml::Helpers
5
+
6
+ task :backup do
7
+ on release_roles :all do
8
+ unless remote_file_exists?
9
+ puts 'No remote application.yml to backup.'
10
+ next
11
+ end
12
+
13
+ begin
14
+ puts 'Creating backup of remote application.yml...'
15
+ create_remote_backup
16
+ puts 'Backup created successfully.'
17
+
18
+ puts 'Cleaning up remote backups...'
19
+ cleanup_remote_backups
20
+ puts 'Remote backups cleaned up successfully.'
21
+ rescue StandardError => e
22
+ puts "Error during backup process: #{e.message}"
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :figaro_yml do
4
+ include Capistrano::Ops::FigaroYml::Paths
5
+ include Capistrano::Ops::FigaroYml::Helpers
6
+ desc 'figaro `application.yml` file checks'
7
+ task :check do
8
+ invoke 'figaro_yml:check_figaro_file_exists'
9
+ invoke 'figaro_yml:check_git_tracking'
10
+ invoke 'figaro_yml:check_config_present'
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :figaro_yml do
4
+ include Capistrano::Ops::FigaroYml::Paths
5
+ include Capistrano::Ops::FigaroYml::Helpers
6
+ task :check_config_present do
7
+ next unless local_figaro_yml(figaro_yml_env).nil?
8
+
9
+ check_config_present_error
10
+ exit 1
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :figaro_yml do
4
+ include Capistrano::Ops::FigaroYml::Paths
5
+ include Capistrano::Ops::FigaroYml::Helpers
6
+ task :check_figaro_file_exists do
7
+ next if File.exist?(figaro_yml_local_path)
8
+
9
+ check_figaro_file_exists_error
10
+ exit 1
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :figaro_yml do
4
+ include Capistrano::Ops::FigaroYml::Paths
5
+ include Capistrano::Ops::FigaroYml::Helpers
6
+ task :check_git_tracking do
7
+ next unless system("git ls-files #{fetch(:figaro_yml_local_path)} --error-unmatch >/dev/null 2>&1")
8
+
9
+ check_git_tracking_error
10
+ exit 1
11
+ end
12
+ end
@@ -1,39 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'figaro_yaml_helper'
4
-
5
3
  namespace :figaro_yml do
6
- include FigaroYmlHelper
7
- rake_roles = fetch(:rake_roles, :app)
4
+ include Capistrano::Ops::FigaroYml::Paths
5
+ include Capistrano::Ops::FigaroYml::Helpers
8
6
 
9
7
  desc 'compare and set the figaro_yml file on the server'
10
8
  task :compare do
11
- env = fetch(:stage).to_s
12
9
  # Read and parse local application.yml
13
- local = local_yaml
10
+ local = local_figaro_yml(figaro_yml_env)
14
11
 
15
12
  # Split into stage-specific and global configurations
16
- local_global_env, local_stage_env = configs(local, env)
13
+ local_global_env, local_stage_env = configs(local, figaro_yml_env)
17
14
 
18
- # puts local_global_env.to_yaml
19
- # puts "\n\n\n"
20
- # puts({ env => local_stage_env }.to_yaml)
21
- on roles(rake_roles) do
15
+ on release_roles :all do
22
16
  # Read and parse remote application.yml
23
- remote = YAML.safe_load(capture("cat #{shared_path}/config/application.yml"))
24
- remote_global_env, remote_stage_env = configs(remote, env)
25
-
26
- # puts remote_global_env.to_yaml
27
- # puts "\n\n\n"
28
- # puts({ env => remote_stage_env }.to_yaml)
29
- # puts "Comparing local and remote application.yml for '#{env}' environment..."
17
+ remote = YAML.safe_load(capture("cat #{figaro_yml_remote_path}"))
18
+ remote_global_env, remote_stage_env = configs(remote, figaro_yml_env)
30
19
 
31
20
  # Compare hashes and handle nil results with empty hashes
32
21
  differences_global = compare_hashes(local_global_env, remote_global_env)
33
22
  differences_stage = compare_hashes(local_stage_env, remote_stage_env)
34
23
 
35
24
  print_changes(differences_global, 'Local application.yml has extra/different global entries compared to remote.')
36
- print_changes(differences_stage, "Local application.yml has extra/different entries in #{env} section compared to remote.") if differences_stage
25
+ if differences_stage
26
+ print_changes(differences_stage, "Local application.yml has extra/different entries in #{figaro_yml_env} section compared to remote.")
27
+ end
37
28
 
38
29
  puts 'No Differences found between remote and local application.yml' unless differences_global || differences_stage
39
30
 
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :figaro_yml do
4
+ include Capistrano::Ops::FigaroYml::Paths
5
+ include Capistrano::Ops::FigaroYml::Helpers
6
+ task :create_local do
7
+ run_locally do
8
+ puts "found #{stages.count} stages"
9
+ yamls_combined = {}
10
+
11
+ stages.each do |f|
12
+ stage = File.basename(f, '.rb')
13
+ puts "download #{stage} application.yml"
14
+ begin
15
+ res = capture "cap #{stage} figaro_yml:get_stage"
16
+ stage_yaml = YAML.safe_load(res)
17
+ stage_yaml[stage.to_s] = stage_yaml[stage.to_s].sort.to_h
18
+ yamls_combined.merge!(stage_yaml) if stage_yaml
19
+ rescue StandardError
20
+ puts "could not get #{stage} application.yml"
21
+ end
22
+ end
23
+
24
+ write_combined_yaml(yamls_combined.sort.to_h)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :figaro_yml do
4
+ include Capistrano::Ops::FigaroYml::Paths
5
+ include Capistrano::Ops::FigaroYml::Helpers
6
+ task :figaro_yml_symlink do
7
+ set :linked_files, fetch(:linked_files, []).push(fetch(:figaro_yml_remote_path))
8
+ end
9
+ after 'deploy:started', 'figaro_yml:figaro_yml_symlink'
10
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :figaro_yml do
4
+ include Capistrano::Ops::FigaroYml::Paths
5
+ include Capistrano::Ops::FigaroYml::Helpers
6
+ task :get do
7
+ if !File.exist?(figaro_yml_local_path)
8
+ invoke 'figaro_yml:create_local'
9
+ else
10
+ local_yml = local_figaro_yml(figaro_yml_env)
11
+ local_global, local_stage = configs(local_yml, figaro_yml_env)
12
+ on release_roles :all do
13
+ remote = capture "cat #{figaro_yml_remote_path}"
14
+ remote_yml = YAML.safe_load(remote).sort.to_h
15
+ remote_global, remote_stage = configs(remote_yml, figaro_yml_env)
16
+ differences_global = compare_hashes(remote_global, local_global || {})
17
+ differences_stage = compare_hashes(remote_stage, local_stage || {})
18
+
19
+ print_changes(differences_global,
20
+ 'Remote application.yml has extra/different global entries compared to local.')
21
+ if differences_stage
22
+ print_changes(differences_stage, "Remote application.yml has extra/different entries in #{figaro_yml_env} section compared to local.")
23
+ end
24
+
25
+ puts 'No Differences found between remote and local application.yml' unless differences_global || differences_stage
26
+
27
+ # ask to overwrite local yml if differences found
28
+ stage_overwrite = ask_to_overwrite("Overwrite local application.yml #{figaro_yml_env} section") if differences_stage
29
+ global_overwrite = ask_to_overwrite('Overwrite local application.yml globals') if differences_global
30
+ puts 'Nothing written to local application.yml' unless stage_overwrite || global_overwrite
31
+ exit unless stage_overwrite || global_overwrite
32
+
33
+ # compose new yml
34
+ composed_yml = {}
35
+ composed_yml.merge!(local_yml) # local yml is always included to avoid losing any data
36
+ composed_yml.merge!(local_global) unless global_overwrite
37
+ composed_yml.merge!(remote_global) if global_overwrite
38
+ composed_yml[figaro_yml_env.to_s] = stage_overwrite ? remote_stage : local_stage
39
+
40
+ # write to new file
41
+ write_combined_yaml(composed_yml.sort.to_h)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :figaro_yml do
4
+ include Capistrano::Ops::FigaroYml::Paths
5
+ include Capistrano::Ops::FigaroYml::Helpers
6
+ rake_roles = fetch(:rake_roles, :app)
7
+
8
+ task :get_stage do
9
+ on roles(rake_roles) do
10
+ raise 'The file does not exist.' unless test "[ -f #{figaro_yml_remote_path} ]"
11
+
12
+ puts capture "cat #{figaro_yml_remote_path}"
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :load do
4
+ task :defaults do
5
+ set :figaro_yml_local_path, 'config/application.yml'
6
+ set :figaro_yml_remote_path, 'config/application.yml'
7
+ set :figaro_yml_env, -> { fetch(:rails_env) || fetch(:stage) }
8
+ set :figaro_yml_remote_backup, false
9
+ end
10
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :figaro_yml do
4
+ include Capistrano::Ops::FigaroYml::Helpers
5
+
6
+ task :rollback do
7
+ on release_roles :all do
8
+ unless remote_backup_exists?
9
+ puts 'No backup of remote application.yml to rollback.'
10
+ next
11
+ end
12
+
13
+ begin
14
+ puts 'Rolling back remote application.yml...'
15
+ rollback_remote_backup
16
+ puts 'Rollback completed successfully.'
17
+ rescue StandardError => e
18
+ puts "Error during rollback process: #{e.message}"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :figaro_yml do
4
+ include Capistrano::Ops::FigaroYml::Paths
5
+ include Capistrano::Ops::FigaroYml::Helpers
6
+
7
+ desc 'Setup figaro `application.yml` file on the server(s)'
8
+ task setup: [:check] do
9
+ content = figaro_yml_content
10
+ on release_roles :all do
11
+ execute :mkdir, '-pv', File.dirname(figaro_yml_remote_path)
12
+ upload! StringIO.new(content), figaro_yml_remote_path
13
+ end
14
+ end
15
+ before 'figaro_yml:setup', 'figaro_yml:backup'
16
+ end
@@ -1,10 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'figaro_yaml_helper'
4
-
5
3
  namespace :figaro_yml do
6
- include FigaroYmlHelper
7
-
4
+ include Capistrano::Ops::FigaroYml::Paths
5
+ include Capistrano::Ops::FigaroYml::Helpers
8
6
  task :sort_local do
9
7
  run_locally do
10
8
  info 'Sorting local application.yml...'
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'capistrano/ops/helper'
4
+ require 'capistrano/ops/figaro_yml/paths'
5
+ require 'capistrano/ops/figaro_yml/helpers'
6
+
7
+ module TaskLoader
8
+ extend Capistrano::Ops::Helper
9
+
10
+ def self.load_tasks_if_gem_present(gem_name, task_path, warning_message)
11
+ if gem_in_gemfile?(gem_name)
12
+ Dir.glob("#{File.expand_path(__dir__)}/#{task_path}/**/*.rake").each { |f| load f }
13
+ else
14
+ puts warning_message
15
+ end
16
+ end
17
+ end
18
+
19
+ TaskLoader.load_tasks_if_gem_present('figaro', 'figaro_yml/tasks', 'WARNING: Gemfile does not include figaro gem which is required for figaro_yml tasks')
20
+ # include Capistrano::Ops::Helper
21
+
22
+ # Dir.glob("#{File.expand_path(__dir__)}/figaro_yml/tasks/*.rake").each { |f| load f }
23
+
24
+ # # gem 'figaro' is required for figaro_yml tasks
25
+
26
+ # figaro_gem = gem_in_gemfile?('figaro')
27
+
28
+ # # check if Gemfile environment includes figaro gem and warn user if not found
29
+ # puts 'WARNING: Gemfile does not include figaro gem which is required for figaro_yml tasks' unless figaro_gem
@@ -0,0 +1,14 @@
1
+ module Capistrano
2
+ module Ops
3
+ module Helper
4
+ def gem_in_gemfile?(gem_name)
5
+ if File.exist?('Gemfile')
6
+ File.foreach('Gemfile') do |line|
7
+ return true if line.include?('gem') && line.include?("'#{gem_name}'") && !line.include?('#')
8
+ end
9
+ end
10
+ false
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :invoke do
4
+ # Defalut to :app roles
5
+ rake_roles = fetch(:rake_roles, :app)
6
+
7
+ desc 'Execute a rake task on a remote server (cap invoke:rake TASK=db:migrate)'
8
+ task :rake do
9
+ task_name = ENV['TASK']
10
+ unless task_name
11
+ puts "\n\nFailed! You need to specify the 'TASK' parameter!",
12
+ 'Usage: cap <stage> invoke:rake TASK=your:task',
13
+ 'Example: cap production invoke:rake TASK=db:migrate'
14
+ exit 1
15
+ end
16
+
17
+ on roles(rake_roles) do
18
+ within current_path do
19
+ with rails_env: fetch(:rails_env) do
20
+ execute :rake, task_name
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ Dir.glob("#{File.expand_path(__dir__)}/invoke/tasks/**/*.rake").each { |f| load f }
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Capistrano
4
+ module Ops
5
+ module Logrotate
6
+ module Helpers
7
+ def config_template
8
+ return nil unless File.exist?(File.expand_path(logrotate_config_file_template, __dir__))
9
+
10
+ ERB.new(File.read(File.expand_path(logrotate_config_file_template, __dir__))).result(binding)
11
+ end
12
+
13
+ def schedule_template
14
+ return nil unless File.exist?(File.expand_path(logrotate_schedule_file_template, __dir__))
15
+
16
+ ERB.new(File.read(File.expand_path(logrotate_schedule_file_template, __dir__))).result(binding)
17
+ end
18
+
19
+ def logrotate_enabled
20
+ test("[ -f #{logrotate_config_file_path} ]") && test("[ -f #{logrotate_schedule_file_path} ]")
21
+ end
22
+
23
+ def logrotate_disabled
24
+ !(test("[ -f #{logrotate_config_file_path} ]") && test("[ -f #{logrotate_schedule_file_path} ]"))
25
+ end
26
+
27
+ def make_basepath
28
+ puts capture "mkdir -pv #{logrotate_basepath}"
29
+ end
30
+
31
+ def delete_files
32
+ puts capture "rm -rfv #{logrotate_basepath}"
33
+ end
34
+
35
+ def whenever(type)
36
+ case type
37
+ when 'clear'
38
+ puts capture :bundle, :exec, :whenever, '--clear-crontab',
39
+ "-f #{logrotate_schedule_file_path} #{fetch(:whenever_identifier)}_logrotate"
40
+ when 'update'
41
+ puts capture :bundle, :exec, :whenever, '--update-crontab', "-f #{logrotate_schedule_file_path}",
42
+ "-i #{fetch(:whenever_identifier)}_logrotate"
43
+ else
44
+ puts 'type not found'
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,47 @@
1
+ require 'pathname'
2
+
3
+ module Capistrano
4
+ module Ops
5
+ module Logrotate
6
+ module Paths
7
+ # local paths
8
+ def logrotate_config_file_template
9
+ Pathname.new fetch(:logrotate_config_file_template)
10
+ end
11
+
12
+ def logrotate_schedule_file_template
13
+ Pathname.new fetch(:logrotate_schedule_file_template)
14
+ end
15
+
16
+ # remote paths
17
+ def logrotate_basepath
18
+ shared_path.join fetch(:logrotate_basepath)
19
+ end
20
+
21
+ def logrotate_config_path
22
+ shared_path.join fetch(:logrotate_config_path)
23
+ end
24
+
25
+ def logrotate_config_file_path
26
+ logrotate_basepath.join logrotate_config_filename
27
+ end
28
+
29
+ def logrotate_schedule_file_path
30
+ logrotate_basepath.join logrotate_schedule_filename
31
+ end
32
+
33
+ def log_file_path
34
+ shared_path.join fetch(:log_file_path)
35
+ end
36
+
37
+ def logrotate_schedule_filename
38
+ File.basename(logrotate_schedule_file_template, '.erb')
39
+ end
40
+
41
+ def logrotate_config_filename
42
+ File.basename(logrotate_config_file_template, '.erb')
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -1,18 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'logrotate_helper'
4
-
5
3
  namespace :logrotate do
6
- include LogrotateHelper
4
+ include Capistrano::Ops::Logrotate::Helpers
5
+ include Capistrano::Ops::Logrotate::Paths
7
6
 
8
7
  desc 'show logrotate state and config'
9
8
  task :check do
10
9
  on roles(:app) do
11
10
  within release_path do
12
- set_config
13
11
  if logrotate_enabled
14
12
  puts "logrotate running with config\n========================="
15
- puts capture "cat #{@config_file_path}"
13
+ puts capture "cat #{logrotate_config_file_path}"
16
14
  else
17
15
  puts 'logrotate disabled'
18
16
  end
@@ -1,15 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'logrotate_helper'
4
-
5
3
  namespace :logrotate do
6
- include LogrotateHelper
7
-
4
+ include Capistrano::Ops::Logrotate::Paths
5
+ include Capistrano::Ops::Logrotate::Helpers
8
6
  desc 'disable logrotate'
9
7
  task :disable do
10
8
  on roles(:app) do
11
9
  within release_path do
12
- set_config
13
10
  if logrotate_disabled
14
11
  puts 'logrotate already disabled'
15
12
  else
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :logrotate do
4
+ include Capistrano::Ops::Logrotate::Helpers
5
+ include Capistrano::Ops::Logrotate::Paths
6
+
7
+ desc 'Enable logrotate for the application'
8
+ task :enable do
9
+ on roles(:app) do
10
+ within release_path do
11
+ @log_file_path = log_file_path
12
+ @shared_path = shared_path
13
+
14
+ if logrotate_enabled
15
+ puts "logrotate already enabled:\n========================="
16
+ puts capture "cat #{logrotate_config_file_path}"
17
+ else
18
+ puts config_template
19
+ puts schedule_template
20
+ make_basepath
21
+ upload! StringIO.new(config_template), logrotate_config_file_path
22
+ upload! StringIO.new(schedule_template), logrotate_schedule_file_path
23
+ whenever 'update' if logrotate_enabled
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :load do
4
+ task :defaults do
5
+ set :logrotate_config_file_template, File.expand_path('templates/logrotate.conf.erb', __dir__)
6
+ set :logrotate_schedule_file_template, File.expand_path('templates/schedule.rb.erb', __dir__)
7
+ set :logrotate_basepath, 'logrotate'
8
+ set :log_file_path, 'log'
9
+ end
10
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'capistrano/ops/helper'
4
+ require 'capistrano/ops/logrotate/helpers'
5
+ require 'capistrano/ops/logrotate/paths'
6
+
7
+ module TaskLoader
8
+ extend Capistrano::Ops::Helper
9
+
10
+ def self.load_tasks_if_gem_present(gem_name, task_path, warning_message)
11
+ if gem_in_gemfile?(gem_name)
12
+ Dir.glob("#{File.expand_path(__dir__)}/#{task_path}/**/*.rake").each { |f| load f }
13
+ else
14
+ puts warning_message
15
+ end
16
+ end
17
+ end
18
+
19
+ TaskLoader.load_tasks_if_gem_present('whenever', 'logrotate/tasks', 'WARNING: Gemfile does not include whenever gem which is required for logrotate tasks')
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Capistrano
4
+ module Ops
5
+ module Logs
6
+ module Helpers
7
+ def trap_interrupt
8
+ trap('INT') do
9
+ print "\rDisconnecting... Done.\n"
10
+ exit 0
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+
5
+ module Capistrano
6
+ module Ops
7
+ module Logs
8
+ module Paths
9
+ def rails_log_file_path
10
+ shared_path.join fetch(:rails_log_file_name) || "log/#{fetch(:rails_env)}.log"
11
+ end
12
+
13
+ def sidekiq_log_file_path
14
+ shared_path.join fetch(:sidekiq_log_file_name) || 'log/sidekiq.log'
15
+ end
16
+
17
+ def sidekiq_error_log_file_path
18
+ shared_path.join fetch(:sidekiq_error_log_file_name) || 'log/sidekiq.error.log'
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :load do
4
+ task :defaults do
5
+ set :rails_log_file_name, nil
6
+ set :sidekiq_log_file_name, nil
7
+ set :sidekiq_error_log_file_name, nil
8
+ end
9
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :logs do
4
+ include Capistrano::Ops::Logs::Paths
5
+ include Capistrano::Ops::Logs::Helpers
6
+
7
+ desc 'Tail Rails logs'
8
+ task :rails do
9
+ on roles(fetch(:rake_roles, :app)) do
10
+ trap_interrupt
11
+
12
+ execute "tail -f #{rails_log_file_path}" do |_channel, stream, data|
13
+ puts data
14
+ break if stream == :err
15
+ end
16
+ end
17
+ end
18
+ end