capistrano-ops 1.0.10 → 1.1.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.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +18 -0
- data/.github/workflows/ci.yml +44 -0
- data/.github/workflows/release.yml +25 -0
- data/.gitignore +1 -0
- data/.rspec +3 -0
- data/.rubocop.yml +79 -19
- data/.rubocop_todo.yml +55 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +347 -0
- data/README.md +14 -5
- data/Rakefile +22 -1
- data/bin/console +1 -1
- data/capistrano-ops.gemspec +13 -10
- data/lib/capistrano/ops/backup/helper.rb +4 -4
- data/lib/capistrano/ops/backup/tasks/database/create.rake +1 -0
- data/lib/capistrano/ops/backup/tasks/database/pull.rake +1 -0
- data/lib/capistrano/ops/backup/tasks/storage/create.rake +1 -0
- data/lib/capistrano/ops/backup/tasks/storage/pull.rake +1 -0
- data/lib/capistrano/ops/figaro_yml/helpers.rb +3 -6
- data/lib/capistrano/ops/figaro_yml/tasks/check.rake +1 -0
- data/lib/capistrano/ops/figaro_yml/tasks/check_config_present.rake +1 -0
- data/lib/capistrano/ops/figaro_yml/tasks/check_figaro_file_exists.rake +1 -0
- data/lib/capistrano/ops/figaro_yml/tasks/check_git_tracking.rake +1 -0
- data/lib/capistrano/ops/figaro_yml/tasks/create_local.rake +1 -0
- data/lib/capistrano/ops/figaro_yml/tasks/figaro_yml_symlink.rake +1 -0
- data/lib/capistrano/ops/figaro_yml/tasks/get.rake +4 -3
- data/lib/capistrano/ops/figaro_yml/tasks/get_stage.rake +1 -0
- data/lib/capistrano/ops/figaro_yml/tasks/sort_local.rake +1 -0
- data/lib/capistrano/ops/figaro_yml.rb +2 -1
- data/lib/capistrano/ops/invoke/tasks/invoke.rake +1 -1
- data/lib/capistrano/ops/logrotate/paths.rb +2 -0
- data/lib/capistrano/ops/logrotate/tasks/disable.rake +1 -0
- data/lib/capistrano/ops/logrotate.rb +2 -1
- data/lib/capistrano/ops/rails/lib/backup/api.rb +1 -1
- data/lib/capistrano/ops/rails/lib/backup/s3.rb +9 -8
- data/lib/capistrano/ops/rails/lib/backup.rb +2 -0
- data/lib/capistrano/ops/rails/lib/notification/api.rb +1 -1
- data/lib/capistrano/ops/rails/lib/notification/slack.rb +4 -4
- data/lib/capistrano/ops/rails/lib/notification/webhook.rb +4 -4
- data/lib/capistrano/ops/rails/lib/tasks/pg/dump.rake +3 -3
- data/lib/capistrano/ops/rails/lib/tasks/pg/postgres_helper.rb +3 -3
- data/lib/capistrano/ops/rails/lib/tasks/pg/remove_old_dumps.rake +1 -1
- data/lib/capistrano/ops/rails/lib/tasks/storage/backup.rake +1 -1
- data/lib/capistrano/ops/rails/lib/tasks/storage/remove_old_backups.rake +2 -2
- data/lib/capistrano/ops/rails/lib/tasks/storage/storage_helper.rb +5 -5
- data/lib/capistrano/ops/version.rb +1 -1
- data/lib/capistrano/ops/whenever.rb +2 -1
- data/lib/capistrano/ops/wkhtmltopdf/tasks/setup.rake +1 -0
- data/scripts/bump_version.rb +172 -0
- data/spec/capistrano/ops/version_spec.rb +9 -0
- data/spec/spec_helper.rb +20 -0
- metadata +92 -30
- data/.travis.yml +0 -13
- data/lib/capistrano/ops/capistrano/v3/tasks/backup.rake +0 -25
data/capistrano-ops.gemspec
CHANGED
|
@@ -15,17 +15,20 @@ Gem::Specification.new do |s|
|
|
|
15
15
|
s.summary = 'devops tasks for rails applications'
|
|
16
16
|
s.description = 'A collection of devops tasks for rails applications'
|
|
17
17
|
s.files = `git ls-files`.split("\n")
|
|
18
|
-
s.test_files = `git ls-files -- test/{functional,unit}/*`.split("\n")
|
|
19
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
|
20
19
|
s.require_paths = ['lib']
|
|
21
20
|
|
|
22
|
-
s.required_ruby_version = '>=
|
|
23
|
-
s.add_dependency 'aws-sdk-s3', '~> 1.
|
|
24
|
-
s.add_dependency 'faraday'
|
|
25
|
-
s.add_dependency 'nokogiri'
|
|
26
|
-
s.add_dependency 'rails'
|
|
27
|
-
s.add_development_dependency 'bundler', '
|
|
28
|
-
s.add_development_dependency '
|
|
29
|
-
s.add_development_dependency '
|
|
30
|
-
s.add_development_dependency '
|
|
21
|
+
s.required_ruby_version = '>= 3.2'
|
|
22
|
+
s.add_dependency 'aws-sdk-s3', '~> 1.208'
|
|
23
|
+
s.add_dependency 'faraday', '>= 2.0', '< 3.0'
|
|
24
|
+
s.add_dependency 'nokogiri', '>= 1.15'
|
|
25
|
+
s.add_dependency 'rails', '>= 7.2', '< 9'
|
|
26
|
+
s.add_development_dependency 'bundler', '>= 2.4', '< 5'
|
|
27
|
+
s.add_development_dependency 'bundler-audit', '~> 0.9'
|
|
28
|
+
s.add_development_dependency 'rake', '~> 13.0'
|
|
29
|
+
s.add_development_dependency 'rspec', '~> 3.0'
|
|
30
|
+
s.add_development_dependency 'rubocop', '~> 1.80'
|
|
31
|
+
s.add_development_dependency 'rubocop-rake', '~> 0.7'
|
|
32
|
+
s.add_development_dependency 'rubocop-rspec', '~> 3.0'
|
|
33
|
+
s.metadata['rubygems_mfa_required'] = 'true'
|
|
31
34
|
end
|
|
@@ -5,7 +5,7 @@ module Capistrano
|
|
|
5
5
|
module Backup
|
|
6
6
|
module Helper
|
|
7
7
|
def backup_file_name(type)
|
|
8
|
-
regex = type == 'storage' ? "'.{0,}
|
|
8
|
+
regex = type == 'storage' ? "'.{0,}.tar.gz'" : "'.{0,}.dump'"
|
|
9
9
|
@backup_file_name ||= capture "cd #{shared_path}/backups && ls -lt | grep -E -i #{regex} | head -n 1 | awk '{print $9}'"
|
|
10
10
|
end
|
|
11
11
|
|
|
@@ -26,7 +26,7 @@ module Capistrano
|
|
|
26
26
|
puts 'Temporary backup deleted'
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
def question(question, default = 'n', &
|
|
29
|
+
def question(question, default = 'n', &)
|
|
30
30
|
print "#{question} #{default.downcase == 'n' ? '(y/N)' : '(Y/n)'}: "
|
|
31
31
|
input = $stdin.gets.strip.downcase
|
|
32
32
|
answer = (input.empty? ? default : input).downcase.to_s
|
|
@@ -34,7 +34,7 @@ module Capistrano
|
|
|
34
34
|
if %w[y n].include?(answer)
|
|
35
35
|
yield(answer == 'y')
|
|
36
36
|
else
|
|
37
|
-
question(question, default, &
|
|
37
|
+
question(question, default, &)
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
40
|
|
|
@@ -47,7 +47,7 @@ module Capistrano
|
|
|
47
47
|
def size_str(size)
|
|
48
48
|
units = %w[B KB MB GB TB]
|
|
49
49
|
e = (Math.log(size) / Math.log(1024)).floor
|
|
50
|
-
s = format('%.2f', size.to_f / 1024**e)
|
|
50
|
+
s = format('%.2f', size.to_f / (1024**e))
|
|
51
51
|
s.sub(/\.?0*$/, units[e])
|
|
52
52
|
end
|
|
53
53
|
end
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require 'yaml'
|
|
4
4
|
|
|
5
|
-
# rubocop:disable Metrics/ModuleLength
|
|
5
|
+
# rubocop:disable-next Metrics/ModuleLength
|
|
6
6
|
module Capistrano
|
|
7
7
|
module Ops
|
|
8
8
|
module FigaroYml
|
|
@@ -63,7 +63,7 @@ module Capistrano
|
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
def local_yaml
|
|
66
|
-
YAML.
|
|
66
|
+
YAML.safe_load_file(figaro_yml_local_path) || {}
|
|
67
67
|
end
|
|
68
68
|
|
|
69
69
|
def figaro_yml_env
|
|
@@ -162,9 +162,7 @@ module Capistrano
|
|
|
162
162
|
|
|
163
163
|
# file helpers
|
|
164
164
|
def write_to_file(file, content)
|
|
165
|
-
File.
|
|
166
|
-
f.write(content)
|
|
167
|
-
end
|
|
165
|
+
File.write(file, content)
|
|
168
166
|
end
|
|
169
167
|
|
|
170
168
|
def write_combined_yaml(yamls_combined)
|
|
@@ -180,4 +178,3 @@ module Capistrano
|
|
|
180
178
|
end
|
|
181
179
|
end
|
|
182
180
|
end
|
|
183
|
-
# rubocop:enable Metrics/ModuleLength
|
|
@@ -3,10 +3,9 @@
|
|
|
3
3
|
namespace :figaro_yml do
|
|
4
4
|
include Capistrano::Ops::FigaroYml::Paths
|
|
5
5
|
include Capistrano::Ops::FigaroYml::Helpers
|
|
6
|
+
|
|
6
7
|
task :get do
|
|
7
|
-
if
|
|
8
|
-
invoke 'figaro_yml:create_local'
|
|
9
|
-
else
|
|
8
|
+
if File.exist?(figaro_yml_local_path)
|
|
10
9
|
local_yml = local_figaro_yml(figaro_yml_env)
|
|
11
10
|
local_global, local_stage, local_rest = configs(local_yml, figaro_yml_env)
|
|
12
11
|
on release_roles :all do
|
|
@@ -40,6 +39,8 @@ namespace :figaro_yml do
|
|
|
40
39
|
# write to new file
|
|
41
40
|
write_combined_yaml(composed_yml.sort.to_h)
|
|
42
41
|
end
|
|
42
|
+
else
|
|
43
|
+
invoke 'figaro_yml:create_local'
|
|
43
44
|
end
|
|
44
45
|
end
|
|
45
46
|
end
|
|
@@ -4,4 +4,5 @@ require 'capistrano/ops/task_loader'
|
|
|
4
4
|
require 'capistrano/ops/figaro_yml/paths'
|
|
5
5
|
require 'capistrano/ops/figaro_yml/helpers'
|
|
6
6
|
|
|
7
|
-
TaskLoader.load_tasks_if_gem_present('figaro', 'figaro_yml/tasks',
|
|
7
|
+
TaskLoader.load_tasks_if_gem_present('figaro', 'figaro_yml/tasks',
|
|
8
|
+
'WARNING: Gemfile does not include figaro gem which is required for figaro_yml tasks')
|
|
@@ -6,7 +6,7 @@ namespace :invoke do
|
|
|
6
6
|
|
|
7
7
|
desc 'Execute a rake task on a remote server (cap invoke:rake TASK=db:migrate)'
|
|
8
8
|
task :rake do
|
|
9
|
-
task_name = ENV
|
|
9
|
+
task_name = ENV.fetch('TASK', nil)
|
|
10
10
|
unless task_name
|
|
11
11
|
puts "\n\nFailed! You need to specify the 'TASK' parameter!",
|
|
12
12
|
'Usage: cap <stage> invoke:rake TASK=your:task',
|
|
@@ -4,4 +4,5 @@ require 'capistrano/ops/task_loader'
|
|
|
4
4
|
require 'capistrano/ops/logrotate/helpers'
|
|
5
5
|
require 'capistrano/ops/logrotate/paths'
|
|
6
6
|
|
|
7
|
-
TaskLoader.load_tasks_if_gem_present('whenever', 'logrotate/tasks',
|
|
7
|
+
TaskLoader.load_tasks_if_gem_present('whenever', 'logrotate/tasks',
|
|
8
|
+
'WARNING: Gemfile does not include whenever gem which is required for logrotate tasks')
|
|
@@ -4,7 +4,7 @@ module Backup
|
|
|
4
4
|
class Api
|
|
5
5
|
attr_accessor :backup_provider, :provider_config
|
|
6
6
|
|
|
7
|
-
def initialize(provider: ENV
|
|
7
|
+
def initialize(provider: ENV.fetch('BACKUP_PROVIDER', nil), provider_config: {})
|
|
8
8
|
self.backup_provider = provider
|
|
9
9
|
self.provider_config = provider_config
|
|
10
10
|
end
|
|
@@ -12,8 +12,9 @@ module Backup
|
|
|
12
12
|
|
|
13
13
|
attr_accessor :endpoint, :region, :access_key_id, :secret_access_key, :s3_resource, :s3_client
|
|
14
14
|
|
|
15
|
-
def initialize(endpoint: ENV
|
|
16
|
-
|
|
15
|
+
def initialize(endpoint: ENV.fetch('S3_BACKUP_ENDPOINT',
|
|
16
|
+
nil), region: ENV.fetch('S3_BACKUP_REGION', nil), access_key_id: ENV.fetch('S3_BACKUP_KEY', nil),
|
|
17
|
+
secret_access_key: ENV.fetch('S3_BACKUP_SECRET', nil))
|
|
17
18
|
self.endpoint = endpoint
|
|
18
19
|
self.region = region
|
|
19
20
|
self.access_key_id = access_key_id
|
|
@@ -31,7 +32,7 @@ module Backup
|
|
|
31
32
|
|
|
32
33
|
def upload(backup_file, key)
|
|
33
34
|
begin
|
|
34
|
-
s3_resource.bucket(ENV
|
|
35
|
+
s3_resource.bucket(ENV.fetch('S3_BACKUP_BUCKET', nil)).object(key).upload_file(backup_file)
|
|
35
36
|
rescue Backup::Error => e
|
|
36
37
|
puts "Upload failed: #{e.message}"
|
|
37
38
|
raise e
|
|
@@ -49,7 +50,7 @@ module Backup
|
|
|
49
50
|
|
|
50
51
|
# rubocop:disable Metrics/MethodLength
|
|
51
52
|
def upload_file_as_stream(file_path, key)
|
|
52
|
-
bucket = ENV
|
|
53
|
+
bucket = ENV.fetch('S3_BACKUP_BUCKET', nil)
|
|
53
54
|
# Calculate total size of the file to be uploaded
|
|
54
55
|
total_size = File.size(file_path)
|
|
55
56
|
chunk_size = calculate_chunk_size(total_size)
|
|
@@ -130,7 +131,7 @@ module Backup
|
|
|
130
131
|
end
|
|
131
132
|
|
|
132
133
|
def upload_folder_as_tar_gz_stream(folder_path, key)
|
|
133
|
-
bucket = ENV
|
|
134
|
+
bucket = ENV.fetch('S3_BACKUP_BUCKET', nil)
|
|
134
135
|
|
|
135
136
|
# Calculate total size of the files to be uploaded
|
|
136
137
|
total_size = calculate_total_size(folder_path)
|
|
@@ -256,7 +257,7 @@ module Backup
|
|
|
256
257
|
end
|
|
257
258
|
|
|
258
259
|
def remove_old_backups(basename, keep: 5)
|
|
259
|
-
all_items = s3_resource.bucket(ENV
|
|
260
|
+
all_items = s3_resource.bucket(ENV.fetch('S3_BACKUP_BUCKET', nil)).objects(prefix: basename).map do |item|
|
|
260
261
|
{ key: item.key, last_modified: item.last_modified }
|
|
261
262
|
end
|
|
262
263
|
|
|
@@ -272,7 +273,7 @@ module Backup
|
|
|
272
273
|
puts "Removing #{month} from S3"
|
|
273
274
|
delete_items.each do |item_obj|
|
|
274
275
|
puts "Removing #{item_obj[:key]} from S3"
|
|
275
|
-
s3_resource.bucket(ENV
|
|
276
|
+
s3_resource.bucket(ENV.fetch('S3_BACKUP_BUCKET', nil)).object(item_obj[:key]).delete
|
|
276
277
|
end
|
|
277
278
|
end
|
|
278
279
|
puts 'Old months removed from S3'
|
|
@@ -286,7 +287,7 @@ module Backup
|
|
|
286
287
|
|
|
287
288
|
current_month_delete_items.each do |item_obj|
|
|
288
289
|
puts "Removing #{item_obj[:key]} from S3"
|
|
289
|
-
s3_resource.bucket(ENV
|
|
290
|
+
s3_resource.bucket(ENV.fetch('S3_BACKUP_BUCKET', nil)).object(item_obj[:key]).delete
|
|
290
291
|
end
|
|
291
292
|
puts 'Old backups removed from S3'
|
|
292
293
|
rescue Backup::Error => e
|
|
@@ -4,7 +4,7 @@ module Notification
|
|
|
4
4
|
class Api
|
|
5
5
|
attr_accessor :notification_type, :notification_level
|
|
6
6
|
|
|
7
|
-
def initialize(notification_type: ENV
|
|
7
|
+
def initialize(notification_type: ENV.fetch('NOTIFICATION_TYPE', nil), notification_level: ENV.fetch('NOTIFICATION_LEVEL', nil))
|
|
8
8
|
self.notification_type = notification_type
|
|
9
9
|
self.notification_level = notification_level || 'error'
|
|
10
10
|
end
|
|
@@ -6,8 +6,8 @@ require 'json'
|
|
|
6
6
|
module Notification
|
|
7
7
|
class Slack
|
|
8
8
|
def initialize
|
|
9
|
-
@slack_secret = ENV
|
|
10
|
-
@slack_channel = ENV
|
|
9
|
+
@slack_secret = ENV.fetch('SLACK_SECRET', nil)
|
|
10
|
+
@slack_channel = ENV.fetch('SLACK_CHANNEL', nil)
|
|
11
11
|
@conn = Faraday.new(url: 'https://slack.com/api/') do |faraday|
|
|
12
12
|
faraday.headers['Content-Type'] = 'application/json'
|
|
13
13
|
faraday.headers['Authorization'] = "Bearer #{@slack_secret}"
|
|
@@ -20,8 +20,8 @@ module Notification
|
|
|
20
20
|
begin
|
|
21
21
|
res = @conn.post('chat.postMessage') do |req|
|
|
22
22
|
req.body = {
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
channel: @slack_channel,
|
|
24
|
+
text: message
|
|
25
25
|
}.to_json
|
|
26
26
|
end
|
|
27
27
|
response = JSON.parse(res.body)
|
|
@@ -7,18 +7,18 @@ module Notification
|
|
|
7
7
|
require 'json'
|
|
8
8
|
|
|
9
9
|
def initialize
|
|
10
|
-
@webhook_url = ENV
|
|
11
|
-
@secret = ENV
|
|
10
|
+
@webhook_url = ENV.fetch('WEBHOOK_URL', nil)
|
|
11
|
+
@secret = ENV.fetch('WEBHOOK_SECRET', nil)
|
|
12
12
|
@conn = Faraday.new(url: @webhook_url) do |faraday|
|
|
13
13
|
faraday.headers['Content-Type'] = 'application/json'
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def generate_signature(payload_body)
|
|
18
|
-
"md5=#{OpenSSL::HMAC.hexdigest('md5', ENV
|
|
18
|
+
"md5=#{OpenSSL::HMAC.hexdigest('md5', ENV.fetch('WEBHOOK_SECRET', nil), payload_body)}"
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
def backup_notification(result, webhook_data,
|
|
21
|
+
def backup_notification(result, webhook_data, notification_level)
|
|
22
22
|
return if @webhook_url.nil? || @secret.nil?
|
|
23
23
|
return if result && notification_level == 'error'
|
|
24
24
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative '
|
|
3
|
+
require_relative 'postgres_helper'
|
|
4
4
|
namespace :pg do
|
|
5
5
|
include PostgresHelper
|
|
6
6
|
|
|
@@ -25,11 +25,11 @@ namespace :pg do
|
|
|
25
25
|
result = system(commandlist)
|
|
26
26
|
|
|
27
27
|
if ENV['BACKUP_PROVIDER'].present? && external_backup && result
|
|
28
|
-
puts "Uploading #{filename} to #{ENV
|
|
28
|
+
puts "Uploading #{filename} to #{ENV.fetch('BACKUP_PROVIDER', nil)}..."
|
|
29
29
|
provider = Backup::Api.new
|
|
30
30
|
begin
|
|
31
31
|
provider.upload("#{backup_path}/#{filename}", filename.to_s, 'file')
|
|
32
|
-
puts "#{filename} uploaded to #{ENV
|
|
32
|
+
puts "#{filename} uploaded to #{ENV.fetch('BACKUP_PROVIDER', nil)}"
|
|
33
33
|
rescue StandardError => e
|
|
34
34
|
puts "#{filename} upload failed: #{e.message}"
|
|
35
35
|
end
|
|
@@ -27,7 +27,7 @@ module PostgresHelper
|
|
|
27
27
|
messages = []
|
|
28
28
|
if result
|
|
29
29
|
messages << "Backup of #{database} successfully finished at #{Time.now}"
|
|
30
|
-
messages << "Backup path
|
|
30
|
+
messages << "Backup path:`#{backup_path}/#{filename}`"
|
|
31
31
|
else
|
|
32
32
|
messages << "Backup of #{database} failed at #{Time.now}"
|
|
33
33
|
end
|
|
@@ -54,14 +54,14 @@ module PostgresHelper
|
|
|
54
54
|
commandlist = []
|
|
55
55
|
commandlist << "export PGPASSWORD='#{password}'"
|
|
56
56
|
commandlist << "cd #{backup_path}"
|
|
57
|
-
commandlist << "pg_dump --no-acl --no-owner #{options.join
|
|
57
|
+
commandlist << "pg_dump --no-acl --no-owner #{options.join} > #{filename}"
|
|
58
58
|
commandlist.join(' && ')
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
def size_str(size)
|
|
62
62
|
units = %w[B KB MB GB TB]
|
|
63
63
|
e = (Math.log(size) / Math.log(1024)).floor
|
|
64
|
-
s = format('%.2f', size.to_f / 1024**e)
|
|
64
|
+
s = format('%.2f', size.to_f / (1024**e))
|
|
65
65
|
s.sub(/\.?0*$/, units[e])
|
|
66
66
|
end
|
|
67
67
|
end
|
|
@@ -12,7 +12,7 @@ namespace :pg do
|
|
|
12
12
|
external_backup = Rails.env.production? || ENV['EXTERNAL_BACKUP_ENABLED'] == 'true'
|
|
13
13
|
|
|
14
14
|
task :remove_old_dumps do
|
|
15
|
-
bash_regex = "'#{@database}.{0,}
|
|
15
|
+
bash_regex = "'#{@database}.{0,}.dump'"
|
|
16
16
|
|
|
17
17
|
unless backups_enabled
|
|
18
18
|
puts 'remove_old_dumps: Backups are disabled'
|
|
@@ -14,7 +14,7 @@ namespace :storage do
|
|
|
14
14
|
@total_external_backups_no = (@env_external_no || ENV['NUMBER_OF_BACKUPS'] || 7).to_i
|
|
15
15
|
desc 'remove old storage backups'
|
|
16
16
|
task :remove_old_backups do
|
|
17
|
-
bash_regex = "'storage_.{0,}
|
|
17
|
+
bash_regex = "'storage_.{0,}.tar.gz'"
|
|
18
18
|
|
|
19
19
|
unless backups_enabled
|
|
20
20
|
puts 'remove_old_backups: Backups are disabled'
|
|
@@ -37,7 +37,7 @@ namespace :storage do
|
|
|
37
37
|
'xargs rm -rf'
|
|
38
38
|
]
|
|
39
39
|
|
|
40
|
-
result = system(commandlist.join(' | ')) if @total_local_backups_no.positive? && local_backup || !local_backup && external_backup
|
|
40
|
+
result = system(commandlist.join(' | ')) if (@total_local_backups_no.positive? && local_backup) || (!local_backup && external_backup)
|
|
41
41
|
puts 'remove_old_backups: local cleanup finished' if result
|
|
42
42
|
|
|
43
43
|
if ENV['BACKUP_PROVIDER'].present? && external_backup
|
|
@@ -9,7 +9,7 @@ module StorageHelper
|
|
|
9
9
|
backups_enabled: env_or_production('BACKUPS_ENABLED'),
|
|
10
10
|
external_backup: env_or_production('EXTERNAL_BACKUP_ENABLED'),
|
|
11
11
|
keep_local_backups: env_or_production('KEEP_LOCAL_STORAGE_BACKUPS'),
|
|
12
|
-
backup_provider: ENV
|
|
12
|
+
backup_provider: ENV.fetch('BACKUP_PROVIDER', nil)
|
|
13
13
|
}
|
|
14
14
|
end
|
|
15
15
|
|
|
@@ -23,7 +23,7 @@ module StorageHelper
|
|
|
23
23
|
messages = []
|
|
24
24
|
if result
|
|
25
25
|
messages << "Backup of storage folder successfully finished at #{Time.now}"
|
|
26
|
-
messages << "Backup path
|
|
26
|
+
messages << "Backup path:`#{@backup_path}/#{@filename}`"
|
|
27
27
|
else
|
|
28
28
|
messages << "Backup of storage folder failed at #{Time.now}"
|
|
29
29
|
end
|
|
@@ -34,19 +34,19 @@ module StorageHelper
|
|
|
34
34
|
@backup_path = settings[:backup_path]
|
|
35
35
|
@date = Time.now.to_i
|
|
36
36
|
@filename = "storage_#{@date}.tar.gz"
|
|
37
|
-
FileUtils.mkdir_p(@backup_path)
|
|
37
|
+
FileUtils.mkdir_p(@backup_path)
|
|
38
38
|
"tar -zcf #{@backup_path}/#{@filename} -C #{settings[:storage_path]} ."
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def size_str(size)
|
|
42
42
|
units = %w[B KB MB GB TB]
|
|
43
43
|
e = (Math.log(size) / Math.log(1024)).floor
|
|
44
|
-
s = format('%.2f', size.to_f / 1024**e)
|
|
44
|
+
s = format('%.2f', size.to_f / (1024**e))
|
|
45
45
|
s.sub(/\.?0*$/, units[e])
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def create_local_backup(filename, storage_path, backup_path)
|
|
49
|
-
FileUtils.mkdir_p(backup_path)
|
|
49
|
+
FileUtils.mkdir_p(backup_path)
|
|
50
50
|
response = system(backup_cmd(backup_path: backup_path, storage_path: storage_path))
|
|
51
51
|
FileUtils.rm_rf("#{@backup_path}/#{filename}") unless response
|
|
52
52
|
puts response ? "Backup created: #{backup_path}/#{@filename} (#{size_str(File.size("#{@backup_path}/#{@filename}"))})" : 'Backup failed removing dump file'
|
|
@@ -2,4 +2,5 @@
|
|
|
2
2
|
|
|
3
3
|
require 'capistrano/ops/task_loader'
|
|
4
4
|
|
|
5
|
-
TaskLoader.load_tasks_if_gem_present('whenever', 'whenever/tasks',
|
|
5
|
+
TaskLoader.load_tasks_if_gem_present('whenever', 'whenever/tasks',
|
|
6
|
+
'WARNING: Gemfile does not include whenever gem which is required for whenever tasks')
|