capistrano-ops 0.2.8 → 0.2.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 07ddd893262d4429b7970dda53b62f8ae613009e3713b81e8498b56b4726ea7a
4
- data.tar.gz: d1b64639900679165f62c709b4abd9af51efa22221674370fe084da62b28bc15
3
+ metadata.gz: 686c30427e0a9b59098e2d10ceeb80b3c1a0d7e69d86bd49e8e15946e29b6437
4
+ data.tar.gz: 76d1e6fc178e8da2d832bca2240b4bb6254b5e1aa566986b8310b1914953398a
5
5
  SHA512:
6
- metadata.gz: 1c918f70a298064b454f7eae961d7d2ff96aa149329df72ee1f9eefda26bc4bd3d8295845788b8511be7cadbb070bff8d6419466e19219e31f0dd5f11c59feea
7
- data.tar.gz: 91acdf541cb7f704320660ee936e8b2261c4172cfb75f10db9d9996c66969aea4ca39b37ab9d1fafa9736ac166b0d6c96c02d8b48e47e20e3d8639fcc5ab72ce
6
+ metadata.gz: 78dce9a9dadc4b2d74651fb96b545918625cd6169ea2995c2f34b71b0ed8d884c60668b6661df92afeed3ce13046dd3ea56a40ac998de5107d566a20eb487c70
7
+ data.tar.gz: cf770e27adac269ecabba02549cef902e161be6be02ad0e35b753f25d8002a0e7e7439a3ffd89c40e2dfd92e6946002dfd134204f02bcf9d247281c63e88baee
data/README.md CHANGED
@@ -1,8 +1,47 @@
1
- # capistrano-ops
1
+ # capistrano-ops - Comprehensive DevOps Utility for Rails 🛠️
2
2
 
3
- Library of useful scripts for DevOps using capistrano with rails.
3
+ The capistrano-ops gem is a valuable library, tailor-made for Rails DevOps professionals, offering an array of beneficial scripts to streamline and enhance operations with Capistrano. The focus is on seamless integration with Capistrano version 3 and above.
4
4
 
5
- **Only supports Capistrano 3 and above**.
5
+ ## Main Features:
6
+
7
+ 🗃️ **Database and Storage Backups:**
8
+
9
+ - Create, pull, and manage backups of your Postgres database and server storage.
10
+ - Delegation of old backup removal for both Postgres database and server storage.
11
+
12
+ 🛠️ **Configuration Management:**
13
+
14
+ - Compare application.yml files between local and server environments using figaro_yml:compare.
15
+ - Fetch server environment variables set via Figaro with figaro_yml:get.
16
+
17
+ 📜 **Logging and Task Management:**
18
+
19
+ - Real-time viewing of Rails server logs.
20
+ - Showcase the server app's crontab generated with the 'whenever' gem.
21
+ - Ability to invoke server-specific rake tasks.
22
+
23
+ 🔔 **Notification Integrations:**
24
+
25
+ - Set up notifications through Slack or generic Webhooks.
26
+ - Customize notification levels (info/error).
27
+
28
+ ⚙️ **Backup Settings Customization:**
29
+
30
+ - Define the number of backups retained, both locally and externally.
31
+ - Toggle backup tasks and external backups.
32
+ - S3 integration for backup storage, including customization of bucket, region, and endpoint details.
33
+
34
+ 📅 **Schedule Tasks:**
35
+
36
+ - Couple with the 'whenever' gem to schedule daily backup creation and old backup removal.
37
+
38
+ 🔗 **Slack & Webhook Integrations:**
39
+
40
+ - Integrate seamlessly with Slack or use webhooks for notifications, alerting you on essential operations or any potential issues.
41
+
42
+ ☁️ **Backup Providers:**
43
+
44
+ - S3 and other S3-compatible services are supported to ensure your data remains secure and accessible.
6
45
 
7
46
  ## Requirements
8
47
 
@@ -85,6 +124,7 @@ production:
85
124
  | NUMBER_OF_EXTERNAL_BACKUPS | number of backups to keep externally (default: nil) | `number` |
86
125
  | BACKUPS_ENABLED | enable/disable backup task (default: Rails.env == 'production') | `boolean` |
87
126
  | EXTERNAL_BACKUP_ENABLED | enable/disable external backup (default: false) (only if 'BACKUPS_ENABLED', needs additional setup) | `boolean` |
127
+ | KEEP_LOCAL_STORAGE_BACKUPS | keep local storage backups (default: Rails.env == 'production') | `boolean` |
88
128
  | DEFAULT_URL | notification message title (default: "#{database} Backup") | `string` |
89
129
  | NOTIFICATION_TYPE | for notification (default: nil) | `string` (`webhook`/`slack`) |
90
130
  | NOTIFICATION_LEVEL | for notification (default: nil) | `string` (`info`/`error`) |
@@ -2,7 +2,9 @@
2
2
 
3
3
  module Backup
4
4
  require 'aws-sdk-s3'
5
+ require 'capistrano/ops/backup/s3_helper'
5
6
  class S3
7
+ include Backup::S3Helper
6
8
  attr_accessor :endpoint, :region, :access_key_id, :secret_access_key, :s3_resource
7
9
 
8
10
  def initialize(endpoint: ENV['S3_BACKUP_ENDPOINT'], region: ENV['S3_BACKUP_REGION'], access_key_id: ENV['S3_BACKUP_KEY'],
@@ -14,7 +16,9 @@ module Backup
14
16
  configuration = {
15
17
  region: region,
16
18
  access_key_id: access_key_id,
17
- secret_access_key: secret_access_key
19
+ secret_access_key: secret_access_key,
20
+ force_path_style: true
21
+
18
22
  }
19
23
  configuration[:endpoint] = endpoint unless endpoint.nil?
20
24
  self.s3_resource = Aws::S3::Resource.new(configuration)
@@ -36,17 +40,30 @@ module Backup
36
40
  end
37
41
 
38
42
  all_items = all_items.sort_by { |hsh| hsh[:last_modified] }.reverse
39
-
40
- count = all_items.count
41
-
42
- if count <= keep
43
- puts 'Nothing to remove'
43
+ months = get_months(all_items)
44
+ old_months = get_old_months(months)
45
+ if old_months&.empty? || old_months.nil?
46
+ puts 'No old months to remove'
47
+ else
48
+ old_months.each do |month|
49
+ items = get_items_by_month(all_items, month)
50
+ delete_items = get_delete_items(items, 1)
51
+ puts "Removing #{month} from S3"
52
+ delete_items.each do |item_obj|
53
+ puts "Removing #{item_obj[:key]} from S3"
54
+ s3_resource.bucket(ENV['S3_BACKUP_BUCKET']).object(item_obj[:key]).delete
55
+ end
56
+ end
57
+ puts 'Old months removed from S3'
58
+ end
59
+ current_month = get_current_month(all_items)
60
+ current_month_delete_items = get_delete_items(current_month, keep)
61
+ if current_month_delete_items&.empty? || current_month_delete_items.nil?
62
+ puts 'No old backups to remove'
44
63
  exit(0)
45
64
  end
46
65
 
47
- delete_items = all_items.slice(keep..-1)
48
-
49
- delete_items.each do |item_obj|
66
+ current_month_delete_items.each do |item_obj|
50
67
  puts "Removing #{item_obj[:key]} from S3"
51
68
  s3_resource.bucket(ENV['S3_BACKUP_BUCKET']).object(item_obj[:key]).delete
52
69
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Backup
4
+ module S3Helper
5
+ def get_delete_items(items, keep)
6
+ items.slice(keep..-1)
7
+ end
8
+
9
+ def get_months(all_items)
10
+ all_items.reverse.map { |m| m[:last_modified].strftime('%Y-%m') }
11
+ end
12
+
13
+ def get_old_months(months)
14
+ months.uniq.reject { |m| m == Time.now.strftime('%Y-%m') }
15
+ end
16
+
17
+ def get_current_month(all_items)
18
+ all_items.select { |item| item[:last_modified].strftime('%Y-%m') == Time.now.strftime('%Y-%m') }
19
+ end
20
+
21
+ def get_items_by_month(all_items, month)
22
+ all_items.select { |item| item[:last_modified].strftime('%Y-%m') == month }
23
+ end
24
+ end
25
+ end
@@ -12,7 +12,7 @@ module BackupHelper
12
12
 
13
13
  def download_backup(backup_file, type)
14
14
  puts "Downloading #{type} backup"
15
- download! "#{shared_path}/backups/#{backup_file}" , backup_file
15
+ download! "#{shared_path}/backups/#{backup_file}", backup_file
16
16
  puts "Download finished\nDeleting temporary backup..."
17
17
  cleanup_backup(backup_file, "Download finished\nDeleting temporary backup...")
18
18
  end
@@ -5,6 +5,7 @@ namespace :storage do
5
5
  backup_path = Rails.root.join(Rails.env.development? ? 'tmp/backups' : '../../shared/backups').to_s
6
6
  backups_enabled = Rails.env.production? || ENV['BACKUPS_ENABLED'] == 'true'
7
7
  external_backup = Rails.env.production? || ENV['EXTERNAL_BACKUP_ENABLED'] == 'true'
8
+ local_backup = Rails.env.production? || ENV['KEEP_LOCAL_STORAGE_BACKUPS'] == 'true'
8
9
 
9
10
  @env_local_no = ENV['NUMBER_OF_LOCAL_BACKUPS'].present? ? ENV['NUMBER_OF_LOCAL_BACKUPS'] : nil
10
11
  @env_external_no = ENV['NUMBER_OF_EXTERNAL_BACKUPS'].present? ? ENV['NUMBER_OF_EXTERNAL_BACKUPS'] : nil
@@ -30,12 +31,12 @@ namespace :storage do
30
31
  commandlist = [
31
32
  "cd #{backup_path} && ls -lt ",
32
33
  "grep -E -i #{bash_regex} ",
33
- "tail -n +#{@total_local_backups_no + 1} ",
34
+ "tail -n +#{local_backup ? (@total_local_backups_no + 1) : 0} ",
34
35
  "awk '{print $9}' ",
35
36
  'xargs rm -rf'
36
37
  ]
37
38
 
38
- result = system(commandlist.join(' | ')) if @total_local_backups_no.positive?
39
+ result = system(commandlist.join(' | ')) if @total_local_backups_no.positive? && local_backup || !local_backup && external_backup
39
40
  puts 'remove_old_backups: local cleanup finished' if result
40
41
 
41
42
  if ENV['BACKUP_PROVIDER'].present? && external_backup
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Capistrano
4
4
  module Ops
5
- VERSION = '0.2.8'
5
+ VERSION = '0.2.10'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capistrano-ops
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.8
4
+ version: 0.2.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Crusius
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-07 00:00:00.000000000 Z
11
+ date: 2024-04-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-s3
@@ -118,6 +118,7 @@ files:
118
118
  - lib/capistrano/ops/backup.rb
119
119
  - lib/capistrano/ops/backup/api.rb
120
120
  - lib/capistrano/ops/backup/s3.rb
121
+ - lib/capistrano/ops/backup/s3_helper.rb
121
122
  - lib/capistrano/ops/capistrano.rb
122
123
  - lib/capistrano/ops/capistrano/v3/tasks/backup.rake
123
124
  - lib/capistrano/ops/capistrano/v3/tasks/backup/backup_helper.rb
@@ -162,7 +163,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
162
163
  - !ruby/object:Gem::Version
163
164
  version: '0'
164
165
  requirements: []
165
- rubygems_version: 3.1.2
166
+ rubygems_version: 3.4.22
166
167
  signing_key:
167
168
  specification_version: 4
168
169
  summary: devops tasks for rails applications