ops_backups 0.1.1 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +20 -13
- data/app/jobs/ops_backups/backup_db_job.rb +6 -3
- data/app/jobs/ops_backups/cleanup_limit_job.rb +1 -1
- data/app/jobs/ops_backups/cleanup_tiered_job.rb +1 -1
- data/app/models/ops_backups/backup.rb +21 -8
- data/config/locales/en.yml +7 -0
- data/lib/generators/ops_backups/activeadmin/activeadmin_generator.rb +10 -0
- data/lib/generators/ops_backups/activeadmin/templates/backup.rb +42 -0
- data/lib/generators/ops_backups/install/install_generator.rb +7 -1
- data/lib/ops_backups/engine.rb +4 -0
- data/lib/ops_backups/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5998e71c3bda4e80392ef2d50e3be95280b5927bb961ab8e3a1d9a614b7788f7
|
4
|
+
data.tar.gz: 8d066ea20d375d5da4156c3f7f1211c67ad6e08604a6e9c5ea1b72c028e3abfc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9b586429bfbba9fbdb3c354743ffb51c2b197afa9ab61367c90cb1d67959bc928ef8b969e8846a43becf58e488e4e999e55dc75fef8a9607e7892ef5b7dd1324
|
7
|
+
data.tar.gz: 20a218a19b9be0a87bdbf5c688c914e1a3083a6e64ec8e94438abe7f174012e15913d23764f3f041d42e0e9bf9c11772d23ed5cacd3157453ecee9cd7ec76ee4
|
data/README.md
CHANGED
@@ -1,28 +1,35 @@
|
|
1
1
|
# OpsBackups
|
2
|
-
|
2
|
+
|
3
|
+
A Ruby gem that provides a simple way to backup (self)-hosted postgres databases to
|
4
|
+
ActiveStorage services like S3, Google Cloud Storage, etc.
|
3
5
|
|
4
6
|
## Usage
|
5
|
-
How to use my plugin.
|
6
7
|
|
7
8
|
## Installation
|
8
|
-
Add this line to your application's Gemfile:
|
9
|
-
|
10
|
-
```ruby
|
11
|
-
gem "ops_backups"
|
12
|
-
```
|
13
9
|
|
14
|
-
And then execute:
|
15
10
|
```bash
|
16
|
-
|
11
|
+
bundle add ops_backups
|
12
|
+
# install migrations
|
13
|
+
# configure solid queu recurring job for a basic backup
|
14
|
+
rails generate ops_backups:install
|
17
15
|
```
|
18
16
|
|
19
|
-
|
17
|
+
# ActiveAdmin Integration
|
18
|
+
|
19
|
+
If you are using ActiveAdmin, you can manage your backups through the admin interface. The generator rails generate ops_backups:activeadmin will create the necessary example configuration.
|
20
|
+
|
20
21
|
```bash
|
21
|
-
|
22
|
+
# add an active admin resource
|
23
|
+
rails generate ops_backups:activeadmin
|
22
24
|
```
|
23
25
|
|
24
|
-
##
|
25
|
-
|
26
|
+
## Available Actions
|
27
|
+
|
28
|
+
- Download Backup: Download the backup file.
|
29
|
+
- Create Versioned Backup: Create a new versioned backup.
|
30
|
+
- Create Unversioned Backup: Create a new unversioned backup, excluding specific tables.
|
31
|
+
|
32
|
+
|
26
33
|
|
27
34
|
## License
|
28
35
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -8,8 +8,11 @@ class OpsBackups::BackupDbJob < ApplicationJob
|
|
8
8
|
# @param tag [String] the tag to assign to the backup
|
9
9
|
# @param exclude_tables [Array<String>] the list of tables to exclude from the backup
|
10
10
|
# @param cleanup_policy [String] the cleanup policy to apply to the backup, one of "retain_tiered_cleanup_policy" or "retain_last_limit_cleanup_policy"
|
11
|
-
def perform(
|
12
|
-
|
13
|
-
|
11
|
+
def perform(options = {})
|
12
|
+
exclude_tables = options[:exclude_tables] || []
|
13
|
+
tag = options[:tag] || (exclude_tables.empty? ? "db_pg_full" : "db_pg_partial")
|
14
|
+
cleanup = options[:cleanup]
|
15
|
+
OpsBackups::Backup.new.db_pg_backup(exclude_tables:, tag:)
|
16
|
+
OpsBackups::Backup.send("#{cleanup}_cleanup_policy", tag: tag) if cleanup.present?
|
14
17
|
end
|
15
18
|
end
|
@@ -10,6 +10,6 @@ class OpsBackups::CleanupLimitJob < ApplicationJob
|
|
10
10
|
#
|
11
11
|
# @example Tasks::CleanupLimit.perform_now(tag: "db_pg_full", limit: 14)
|
12
12
|
def perform(tag: "db_pg_full", limit: 14)
|
13
|
-
|
13
|
+
OpsBackups::Backup.retain_last_limit_cleanup_policy(tag: tag, limit: limit)
|
14
14
|
end
|
15
15
|
end
|
@@ -9,6 +9,6 @@ class OpsBackups::CleanupTieredJob < ApplicationJob
|
|
9
9
|
#
|
10
10
|
# @example Tasks::CleanupTiered.perform_now(tag: "db_pg_full")
|
11
11
|
def perform(tag: "db_pg_full")
|
12
|
-
|
12
|
+
OpsBackups::Backup.retain_tiered_cleanup_policy(tag: tag)
|
13
13
|
end
|
14
14
|
end
|
@@ -1,23 +1,36 @@
|
|
1
1
|
module OpsBackups
|
2
|
-
class Backup <
|
2
|
+
class Backup < ActiveRecord::Base
|
3
3
|
# has_one_attached :backup_file, service: :backup_storage
|
4
4
|
has_one_attached :backup_file, service: :backups
|
5
5
|
self.table_name = "ops_backups"
|
6
6
|
|
7
7
|
default_scope { order(updated_at: :desc) }
|
8
8
|
|
9
|
-
def
|
10
|
-
|
11
|
-
|
9
|
+
def self.ransackable_attributes(auth_object = nil)
|
10
|
+
[ "created_at", "id", "name", "new_id", "tag", "updated_at" ]
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.test
|
14
|
+
"self.test"
|
15
|
+
end
|
16
|
+
|
17
|
+
def hoho
|
18
|
+
"hihi"
|
19
|
+
end
|
20
|
+
|
21
|
+
def db_pg_backup(tag: nil, exclude_tables: [])
|
12
22
|
db_url = ENV["DATABASE_URL"]
|
23
|
+
tag ||= exclude_tables.empty? ? "db_pg_full" : "db_pg_partial" # if tag.empty?
|
13
24
|
self.tag = tag
|
14
|
-
self.name =
|
25
|
+
self.name = "pg_#{db_url.split('/').last}_backup_#{Time.now.to_i}.dump"
|
15
26
|
save!
|
16
|
-
|
17
|
-
|
27
|
+
Rails.logger.info("Backing up database")
|
28
|
+
# exclude_tables = []
|
29
|
+
filename = self.name
|
30
|
+
Tempfile.open("pgbackup") do |tempfile|
|
18
31
|
begin
|
19
32
|
excluded_tables_param = exclude_tables.map { |table| "--exclude-table-data=\#{table}" }.join(" ")
|
20
|
-
command = ["pg_dump", "--no-owner", excluded_tables_param, "-v", "-Fc", "-f", tempfile.path, db_url]
|
33
|
+
command = [ "pg_dump", "--no-owner", excluded_tables_param, "-v", "-Fc", "-f", tempfile.path, db_url ].reject(&:empty?)
|
21
34
|
|
22
35
|
stdout, stderr, status = Open3.capture3(*command)
|
23
36
|
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class OpsBackups::ActiveadminGenerator < Rails::Generators::Base
|
2
|
+
source_root File.expand_path("templates", __dir__)
|
3
|
+
|
4
|
+
desc "Copies the ActiveAdmin backup configuration to your application."
|
5
|
+
|
6
|
+
def copy_admin_backup
|
7
|
+
copy_file "backup.rb", Rails.root.join("app", "admin", "ops_backups", "backup.rb")
|
8
|
+
say "Copied admin/backup.rb to app/admin/ops_backups/backup.rb.", :green
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
ActiveAdmin.register OpsBackups::Backup do
|
2
|
+
menu parent: "Ops", label: I18n.t("admin.ops.backup")
|
3
|
+
|
4
|
+
# Set the default sort order
|
5
|
+
config.sort_order = "updated_at DESC"
|
6
|
+
|
7
|
+
actions :index, :destroy
|
8
|
+
|
9
|
+
filter :name
|
10
|
+
filter :tag
|
11
|
+
|
12
|
+
index title: I18n.t("admin.ops.backup") do
|
13
|
+
selectable_column
|
14
|
+
column :name do |backup|
|
15
|
+
link_to(backup.name, download_backup_admin_ops_backups_backup_path(backup), class: "member_link")
|
16
|
+
end
|
17
|
+
column :tag
|
18
|
+
column :size do |backup|
|
19
|
+
backup.backup_file.attached? ? number_to_human_size(backup.backup_file.byte_size) : "N/A"
|
20
|
+
end
|
21
|
+
column :updated_at
|
22
|
+
column :duration do |backup|
|
23
|
+
Time.at((backup.updated_at - backup.created_at)).utc.strftime("%H:%M:%S")
|
24
|
+
end
|
25
|
+
actions
|
26
|
+
end
|
27
|
+
|
28
|
+
member_action :download_backup, method: :get do
|
29
|
+
redirect_to resource.backup_file.url(disposition: :attachment), allow_other_host: true
|
30
|
+
end
|
31
|
+
|
32
|
+
# an action that creates a new backup
|
33
|
+
collection_action :backup_db, method: :post do
|
34
|
+
OpsBackups::BackupDbJob.perform_later(tag: "db_pg_full")
|
35
|
+
redirect_to admin_ops_backups_backups_path, notice: I18n.t("admin.ops.backup_scheduled")
|
36
|
+
end
|
37
|
+
|
38
|
+
# add a button to the top of the index page
|
39
|
+
action_item :backup_db, only: :index do
|
40
|
+
link_to(I18n.t("admin.ops.backup_db"), backup_db_admin_ops_backups_backups_path, method: :post, class: "action-item-button")
|
41
|
+
end
|
42
|
+
end
|
@@ -35,7 +35,7 @@ class OpsBackups::InstallGenerator < Rails::Generators::Base
|
|
35
35
|
recurring_file = Rails.root.join("config", "recurring.yml")
|
36
36
|
|
37
37
|
if File.exist?(recurring_file)
|
38
|
-
recurring_config = <<~YAML.lines.map { |line| "
|
38
|
+
recurring_config = <<~YAML.lines.map { |line| " #{line}" }.join
|
39
39
|
backup_db:
|
40
40
|
class: OpsBackups::BackupDbJob
|
41
41
|
args: [tag: "db_pg_backup", cleanup: "retain_tiered_cleanup_policy"]
|
@@ -47,5 +47,11 @@ class OpsBackups::InstallGenerator < Rails::Generators::Base
|
|
47
47
|
else
|
48
48
|
say "config/recurring.yml not found. Please create it and re-run this generator.", :red
|
49
49
|
end
|
50
|
+
|
51
|
+
# # copy the admin/backup.rb file to app/admin/ops_backups/backup.rb
|
52
|
+
# def copy_admin_backup
|
53
|
+
# copy_file "admin/backup.rb", Rails.root.join("app", "admin", "ops_backups", "backup.rb")
|
54
|
+
# say "Copied admin/backup.rb to app/admin/ops_backups/backup.rb.", :green
|
55
|
+
# end
|
50
56
|
end
|
51
57
|
end
|
data/lib/ops_backups/engine.rb
CHANGED
data/lib/ops_backups/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ops_backups
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Koen Handekyn
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-11-
|
11
|
+
date: 2024-11-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -46,8 +46,11 @@ files:
|
|
46
46
|
- app/models/ops_backups/application_record.rb
|
47
47
|
- app/models/ops_backups/backup.rb
|
48
48
|
- app/views/layouts/ops_backups/application.html.erb
|
49
|
+
- config/locales/en.yml
|
49
50
|
- config/routes.rb
|
50
51
|
- db/migrate/20241114173612_create_ops_backups.rb
|
52
|
+
- lib/generators/ops_backups/activeadmin/activeadmin_generator.rb
|
53
|
+
- lib/generators/ops_backups/activeadmin/templates/backup.rb
|
51
54
|
- lib/generators/ops_backups/install/USAGE
|
52
55
|
- lib/generators/ops_backups/install/install_generator.rb
|
53
56
|
- lib/ops_backups.rb
|