ops_backups 0.1.1 → 0.1.3
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/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
|