ops_backups 0.1.0 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +18 -115
- data/app/controllers/ops_backups/application_controller.rb +4 -0
- data/app/helpers/{ops → ops_backups}/application_helper.rb +1 -1
- data/app/jobs/ops_backups/application_job.rb +4 -0
- data/app/jobs/{ops/backups → ops_backups}/backup_db_job.rb +7 -4
- data/app/jobs/{ops/backups → ops_backups}/cleanup_limit_job.rb +2 -2
- data/app/jobs/{ops/backups → ops_backups}/cleanup_tiered_job.rb +2 -2
- data/app/mailers/ops_backups/application_mailer.rb +6 -0
- data/app/models/ops_backups/application_record.rb +5 -0
- data/app/models/{ops/backups → ops_backups}/backup.rb +24 -12
- data/app/views/layouts/{ops → ops_backups}/application.html.erb +2 -2
- data/config/routes.rb +1 -1
- 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/USAGE +8 -0
- data/lib/generators/ops_backups/install/install_generator.rb +57 -0
- data/lib/ops_backups/engine.rb +11 -0
- data/lib/ops_backups/version.rb +3 -0
- data/lib/ops_backups.rb +6 -0
- data/lib/tasks/{ops_tasks.rake → ops_backups_tasks.rake} +1 -1
- metadata +21 -16
- data/app/controllers/ops/backups/application_controller.rb +0 -6
- data/app/jobs/ops/backups/application_job.rb +0 -6
- data/app/models/ops/backups/application_record.rb +0 -8
- data/lib/ops/backups/backups.rb +0 -8
- data/lib/ops/backups/engine.rb +0 -7
- data/lib/ops/backups/version.rb +0 -5
- /data/app/assets/stylesheets/{ops → ops_backups}/application.css +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3024502438b6655823c65f47d783165f1d91718f98ee68b1b0ff945f20497ffe
|
4
|
+
data.tar.gz: d5dfa0b6d4b128a557213e30591d7121245b1544cf1f58a7617cfb102de61584
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 420151cb8f9cd51361d45525f80409ea535957f9c54702826ef93f5e32f370515a4ffd3e799a8e9c4731db9b8f2fa616a40702ca0421d5e334d313cdcb0aa5a5
|
7
|
+
data.tar.gz: 329f8fbbbcda7b9052cc4760afce2141ddb9120ad77dfd08c5fcc066cfdcb5b71f0e1e10b3a27157ade75dd3e8ece8635adf59db1a5b141f821c3efd751b23e2
|
data/README.md
CHANGED
@@ -1,132 +1,35 @@
|
|
1
|
-
#
|
1
|
+
# OpsBackups
|
2
2
|
|
3
|
-
|
4
|
-
|
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.
|
5
5
|
|
6
6
|
## Usage
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
To configure the Ops gem, you need to set up the following environment variables:
|
11
|
-
- `DATABASE_URL`: The URL of the PostgreSQL database to backup.
|
12
|
-
|
13
|
-
Set up Active Storage for backups (e.g., Amazon S3 for production). We expect a service named `:backup_storage` to be configured.
|
14
|
-
|
15
|
-
```yaml
|
16
|
-
backup_storage:
|
17
|
-
service: S3
|
18
|
-
access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %>
|
19
|
-
secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %>
|
20
|
-
region: <%= ENV['AWS_REGION'] %>
|
21
|
-
bucket: backups
|
22
|
-
```
|
23
|
-
### Backup Method
|
24
|
-
|
25
|
-
The `Ops::Backup` class provides a method to perform a PostgreSQL database backup:
|
26
|
-
|
27
|
-
- `db_pg_backup(exclude_tables: [], tag: nil)`: This method performs a full backup of the database, optionally excluding specified tables. The backup is tagged and saved as an attachment.
|
28
|
-
|
29
|
-
example:
|
8
|
+
## Installation
|
30
9
|
|
31
|
-
```
|
32
|
-
|
10
|
+
```bash
|
11
|
+
bundle add ops_backups
|
12
|
+
# install migrations
|
13
|
+
# configure solid queu recurring job for a basic backup
|
14
|
+
rails generate ops_backups:install
|
33
15
|
```
|
34
16
|
|
35
|
-
|
36
|
-
|
37
|
-
Ops gem provides two backup retention strategies:
|
38
|
-
|
39
|
-
1. **Tiered Cleanup Policy**:
|
40
|
-
- Keeps all backups from the last day.
|
41
|
-
- Keeps the last backup of each day from the last week (except the last day).
|
42
|
-
- Keeps the last backup of each week from the last month (except the last week).
|
43
|
-
- Keeps the last backup of each month before the last month.
|
44
|
-
|
45
|
-
example:
|
46
|
-
```ruby
|
47
|
-
Ops::CleanupTiered.new.cleanup("db_pg_unversioned")
|
48
|
-
```
|
49
|
-
|
50
|
-
This policy can be applied using the `Ops::CleanupTieredJob`.
|
51
|
-
|
52
|
-
2. **Limit Cleanup Policy**:
|
53
|
-
- Keeps the last N backups, where N is specified by the `limit` parameter.
|
54
|
-
|
55
|
-
example:
|
56
|
-
```ruby
|
57
|
-
Ops::CleanupLimit.new.cleanup("db_pg_unversioned", limit: 14)
|
58
|
-
```
|
59
|
-
|
60
|
-
This policy can be applied using the `Ops::CleanupLimitJob`.
|
61
|
-
|
62
|
-
### Using SolidQueue Schedule
|
17
|
+
# ActiveAdmin Integration
|
63
18
|
|
64
|
-
|
65
|
-
```ruby
|
66
|
-
SolidQueue.schedule(Ops::BackupDbJob.new, cron: '0 0 * * *', args: { tag: "db_pg_full", exclude_tables: [], cleanup: "retain_last_limit" }) # This schedules the backup job to run daily at midnight
|
67
|
-
```
|
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.
|
68
20
|
|
69
|
-
2. Schedule the cleanup job with a tiered policy:
|
70
|
-
```ruby
|
71
|
-
SolidQueue.schedule(Ops::CleanupTieredJob.new, cron: '0 1 * * *', args: { tag: "db_pg_full" }) # This schedules the tiered cleanup job to run daily at 1 AM
|
72
|
-
```
|
73
|
-
|
74
|
-
3. Schedule the cleanup job with a limit policy:
|
75
|
-
```ruby
|
76
|
-
SolidQueue.schedule(Ops::CleanupLimitJob.new, cron: '0 2 * * *', args: { tag: "db_pg_full", limit: 14 }) # This schedules the limit cleanup job to run daily at 2 AM
|
77
|
-
```
|
78
|
-
|
79
|
-
### Using `recurring.yml` from SolidQueue
|
80
|
-
|
81
|
-
Alternatively, you can configure recurring tasks using `recurring.yml` in your SolidQueue configuration:
|
82
|
-
|
83
|
-
1. Create or update the `recurring.yml` file in your application's config directory:
|
84
|
-
```yaml
|
85
|
-
# filepath: config/recurring.yml
|
86
|
-
backup_db_job:
|
87
|
-
cron: "0 0 * * *"
|
88
|
-
class: "Ops::BackupDbJob"
|
89
|
-
args:
|
90
|
-
tag: "db_pg_full"
|
91
|
-
exclude_tables: []
|
92
|
-
cleanup: "retain_last_limit"
|
93
|
-
|
94
|
-
cleanup_tiered_job:
|
95
|
-
cron: "0 1 * * *"
|
96
|
-
class: "Ops::CleanupTieredJob"
|
97
|
-
args:
|
98
|
-
tag: "db_pg_full"
|
99
|
-
|
100
|
-
cleanup_limit_job:
|
101
|
-
cron: "0 2 * * *"
|
102
|
-
class: "Ops::CleanupLimitJob"
|
103
|
-
args:
|
104
|
-
tag: "db_pg_full"
|
105
|
-
limit: 14
|
106
|
-
```
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
## Installation
|
111
|
-
Add this line to your application's Gemfile:
|
112
|
-
|
113
|
-
```ruby
|
114
|
-
gem "ops"
|
115
|
-
```
|
116
|
-
|
117
|
-
And then execute:
|
118
21
|
```bash
|
119
|
-
|
22
|
+
# add an active admin resource
|
23
|
+
rails generate ops_backups:activeadmin
|
120
24
|
```
|
121
25
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
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.
|
126
31
|
|
127
|
-
## Contributing
|
128
32
|
|
129
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/koenhandekyn/ops.
|
130
33
|
|
131
34
|
## License
|
132
35
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -1,15 +1,18 @@
|
|
1
1
|
# typed: true
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
class
|
4
|
+
class OpsBackups::BackupDbJob < ApplicationJob
|
5
5
|
queue_as :operations
|
6
6
|
|
7
7
|
# perform a full backup of the database
|
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
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Cleanup job for limit backup policy
|
4
|
-
class
|
4
|
+
class OpsBackups::CleanupLimitJob < ApplicationJob
|
5
5
|
queue_as :operations
|
6
6
|
|
7
7
|
# @param [String] tag
|
@@ -10,6 +10,6 @@ class Ops::Backups::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
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Cleanup job for tiered backup policy
|
4
|
-
class
|
4
|
+
class OpsBackups::CleanupTieredJob < ApplicationJob
|
5
5
|
queue_as :operations
|
6
6
|
|
7
7
|
# @param [String] tag
|
@@ -9,6 +9,6 @@ class Ops::Backups::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,24 +1,36 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
|
4
|
-
class Ops::Backups::Backup < ApplicationRecord
|
1
|
+
module OpsBackups
|
2
|
+
class Backup < ActiveRecord::Base
|
5
3
|
# has_one_attached :backup_file, service: :backup_storage
|
6
|
-
has_one_attached :backup_file
|
4
|
+
has_one_attached :backup_file, service: :backups
|
5
|
+
self.table_name = "ops_backups"
|
7
6
|
|
8
7
|
default_scope { order(updated_at: :desc) }
|
9
8
|
|
10
|
-
def
|
11
|
-
|
12
|
-
|
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: [])
|
13
22
|
db_url = ENV["DATABASE_URL"]
|
23
|
+
tag ||= exclude_tables.empty? ? "db_pg_full" : "db_pg_partial" # if tag.empty?
|
14
24
|
self.tag = tag
|
15
|
-
self.name =
|
25
|
+
self.name = "pg_#{db_url.split('/').last}_backup_#{Time.now.to_i}.dump"
|
16
26
|
save!
|
17
|
-
|
18
|
-
|
27
|
+
Rails.logger.info("Backing up database")
|
28
|
+
# exclude_tables = []
|
29
|
+
filename = self.name
|
30
|
+
Tempfile.open("pgbackup") do |tempfile|
|
19
31
|
begin
|
20
32
|
excluded_tables_param = exclude_tables.map { |table| "--exclude-table-data=\#{table}" }.join(" ")
|
21
|
-
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?)
|
22
34
|
|
23
35
|
stdout, stderr, status = Open3.capture3(*command)
|
24
36
|
|
@@ -1,13 +1,13 @@
|
|
1
1
|
<!DOCTYPE html>
|
2
2
|
<html>
|
3
3
|
<head>
|
4
|
-
<title>Ops</title>
|
4
|
+
<title>Ops backups</title>
|
5
5
|
<%= csrf_meta_tags %>
|
6
6
|
<%= csp_meta_tag %>
|
7
7
|
|
8
8
|
<%= yield :head %>
|
9
9
|
|
10
|
-
<%= stylesheet_link_tag
|
10
|
+
<%= stylesheet_link_tag "ops_backups/application", media: "all" %>
|
11
11
|
</head>
|
12
12
|
<body>
|
13
13
|
|
data/config/routes.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
|
1
|
+
OpsBackups::Engine.routes.draw do
|
2
2
|
end
|
@@ -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
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class OpsBackups::InstallGenerator < Rails::Generators::Base
|
2
|
+
source_root File.expand_path("templates", __dir__)
|
3
|
+
|
4
|
+
desc "Copies migrations and adds a storage service configuration to storage.yml"
|
5
|
+
|
6
|
+
def copy_migrations
|
7
|
+
rake "railties:install:migrations FROM=ops_backups"
|
8
|
+
say "Migrations copied to your application.", :green
|
9
|
+
end
|
10
|
+
|
11
|
+
def add_storage_service
|
12
|
+
storage_file = Rails.root.join("config", "storage.yml")
|
13
|
+
|
14
|
+
if File.exist?(storage_file)
|
15
|
+
service_config = <<~YAML
|
16
|
+
|
17
|
+
backups:
|
18
|
+
service: Disk
|
19
|
+
root: <%= Rails.root.join("storage") %>
|
20
|
+
# service: S3
|
21
|
+
# access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %>
|
22
|
+
# secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %>
|
23
|
+
# region: <%= ENV['AWS_REGION'] %>
|
24
|
+
# bucket: allcrux-backups
|
25
|
+
YAML
|
26
|
+
|
27
|
+
append_to_file storage_file, service_config
|
28
|
+
say "Added 'backups' service to storage.yml.", :green
|
29
|
+
else
|
30
|
+
say "config/storage.yml not found. Please create it and re-run this generator.", :red
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def add_recurring_jobs
|
35
|
+
recurring_file = Rails.root.join("config", "recurring.yml")
|
36
|
+
|
37
|
+
if File.exist?(recurring_file)
|
38
|
+
recurring_config = <<~YAML.lines.map { |line| " #{line}" }.join
|
39
|
+
backup_db:
|
40
|
+
class: OpsBackups::BackupDbJob
|
41
|
+
args: [tag: "db_pg_backup", cleanup: "retain_tiered_cleanup_policy"]
|
42
|
+
schedule: every hour
|
43
|
+
YAML
|
44
|
+
|
45
|
+
append_to_file recurring_file, recurring_config
|
46
|
+
say "Added 'recurring' jobs to recurring.yml.", :green
|
47
|
+
else
|
48
|
+
say "config/recurring.yml not found. Please create it and re-run this generator.", :red
|
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
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module OpsBackups
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
isolate_namespace OpsBackups
|
4
|
+
|
5
|
+
initializer :append_migrations do |app|
|
6
|
+
unless app.root.to_s.match? root.to_s
|
7
|
+
app.config.paths["db/migrate"].concat(config.paths["db/migrate"].expanded)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/lib/ops_backups.rb
ADDED
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.2
|
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
|
@@ -35,22 +35,27 @@ files:
|
|
35
35
|
- MIT-LICENSE
|
36
36
|
- README.md
|
37
37
|
- Rakefile
|
38
|
-
- app/assets/stylesheets/
|
39
|
-
- app/controllers/
|
40
|
-
- app/helpers/
|
41
|
-
- app/jobs/
|
42
|
-
- app/jobs/
|
43
|
-
- app/jobs/
|
44
|
-
- app/jobs/
|
45
|
-
- app/
|
46
|
-
- app/models/
|
47
|
-
- app/
|
38
|
+
- app/assets/stylesheets/ops_backups/application.css
|
39
|
+
- app/controllers/ops_backups/application_controller.rb
|
40
|
+
- app/helpers/ops_backups/application_helper.rb
|
41
|
+
- app/jobs/ops_backups/application_job.rb
|
42
|
+
- app/jobs/ops_backups/backup_db_job.rb
|
43
|
+
- app/jobs/ops_backups/cleanup_limit_job.rb
|
44
|
+
- app/jobs/ops_backups/cleanup_tiered_job.rb
|
45
|
+
- app/mailers/ops_backups/application_mailer.rb
|
46
|
+
- app/models/ops_backups/application_record.rb
|
47
|
+
- app/models/ops_backups/backup.rb
|
48
|
+
- app/views/layouts/ops_backups/application.html.erb
|
48
49
|
- config/routes.rb
|
49
50
|
- db/migrate/20241114173612_create_ops_backups.rb
|
50
|
-
- lib/
|
51
|
-
- lib/
|
52
|
-
- lib/
|
53
|
-
- lib/
|
51
|
+
- lib/generators/ops_backups/activeadmin/activeadmin_generator.rb
|
52
|
+
- lib/generators/ops_backups/activeadmin/templates/backup.rb
|
53
|
+
- lib/generators/ops_backups/install/USAGE
|
54
|
+
- lib/generators/ops_backups/install/install_generator.rb
|
55
|
+
- lib/ops_backups.rb
|
56
|
+
- lib/ops_backups/engine.rb
|
57
|
+
- lib/ops_backups/version.rb
|
58
|
+
- lib/tasks/ops_backups_tasks.rake
|
54
59
|
homepage: https://github.com/koenhandekyn/ops-backups
|
55
60
|
licenses:
|
56
61
|
- MIT
|
data/lib/ops/backups/backups.rb
DELETED
data/lib/ops/backups/engine.rb
DELETED
data/lib/ops/backups/version.rb
DELETED
File without changes
|