backy_rb 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.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. data/.drone.yml +13 -0
  3. data/.idea/.gitignore +8 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +23 -0
  6. data/CHANGELOG.md +5 -0
  7. data/Gemfile +16 -0
  8. data/Gemfile.lock +120 -0
  9. data/README.md +36 -0
  10. data/Rakefile +10 -0
  11. data/backy.gemspec +45 -0
  12. data/bucky.png +0 -0
  13. data/config/database.example.yml +15 -0
  14. data/dummy/psql/.gitattributes +7 -0
  15. data/dummy/psql/.gitignore +22 -0
  16. data/dummy/psql/.ruby-version +1 -0
  17. data/dummy/psql/Gemfile +34 -0
  18. data/dummy/psql/Gemfile.lock +207 -0
  19. data/dummy/psql/README.md +24 -0
  20. data/dummy/psql/Rakefile +6 -0
  21. data/dummy/psql/app/assets/config/manifest.js +2 -0
  22. data/dummy/psql/app/assets/images/.keep +0 -0
  23. data/dummy/psql/app/assets/stylesheets/application.css +15 -0
  24. data/dummy/psql/app/controllers/application_controller.rb +2 -0
  25. data/dummy/psql/app/controllers/concerns/.keep +0 -0
  26. data/dummy/psql/app/controllers/posts_controller.rb +59 -0
  27. data/dummy/psql/app/helpers/application_helper.rb +2 -0
  28. data/dummy/psql/app/helpers/posts_helper.rb +2 -0
  29. data/dummy/psql/app/models/application_record.rb +3 -0
  30. data/dummy/psql/app/models/concerns/.keep +0 -0
  31. data/dummy/psql/app/models/post.rb +2 -0
  32. data/dummy/psql/app/views/layouts/application.html.erb +15 -0
  33. data/dummy/psql/app/views/posts/_form.html.erb +27 -0
  34. data/dummy/psql/app/views/posts/_post.html.erb +12 -0
  35. data/dummy/psql/app/views/posts/edit.html.erb +10 -0
  36. data/dummy/psql/app/views/posts/index.html.erb +14 -0
  37. data/dummy/psql/app/views/posts/new.html.erb +9 -0
  38. data/dummy/psql/app/views/posts/show.html.erb +10 -0
  39. data/dummy/psql/bin/bundle +109 -0
  40. data/dummy/psql/bin/rails +4 -0
  41. data/dummy/psql/bin/rake +4 -0
  42. data/dummy/psql/bin/setup +33 -0
  43. data/dummy/psql/config/application.rb +43 -0
  44. data/dummy/psql/config/boot.rb +3 -0
  45. data/dummy/psql/config/credentials.yml.enc +1 -0
  46. data/dummy/psql/config/database.yml +87 -0
  47. data/dummy/psql/config/environment.rb +5 -0
  48. data/dummy/psql/config/environments/development.rb +62 -0
  49. data/dummy/psql/config/environments/production.rb +75 -0
  50. data/dummy/psql/config/environments/test.rb +50 -0
  51. data/dummy/psql/config/locales/en.yml +33 -0
  52. data/dummy/psql/config/master.key +1 -0
  53. data/dummy/psql/config/puma.rb +43 -0
  54. data/dummy/psql/config/routes.rb +7 -0
  55. data/dummy/psql/config.ru +6 -0
  56. data/dummy/psql/db/migrate/20230330203226_create_posts.rb +10 -0
  57. data/dummy/psql/db/schema.rb +23 -0
  58. data/dummy/psql/db/seeds.rb +8 -0
  59. data/dummy/psql/log/.keep +0 -0
  60. data/dummy/psql/public/404.html +67 -0
  61. data/dummy/psql/public/422.html +67 -0
  62. data/dummy/psql/public/500.html +66 -0
  63. data/dummy/psql/public/apple-touch-icon-precomposed.png +0 -0
  64. data/dummy/psql/public/apple-touch-icon.png +0 -0
  65. data/dummy/psql/public/favicon.ico +0 -0
  66. data/dummy/psql/public/robots.txt +1 -0
  67. data/dummy/psql/tmp/.keep +0 -0
  68. data/dummy/psql/tmp/pids/.keep +0 -0
  69. data/lib/backy/app_config.rb +11 -0
  70. data/lib/backy/cli.rb +0 -0
  71. data/lib/backy/configuration.rb +66 -0
  72. data/lib/backy/db.rb +29 -0
  73. data/lib/backy/list.rb +18 -0
  74. data/lib/backy/pg_dump.rb +39 -0
  75. data/lib/backy/pg_restore.rb +27 -0
  76. data/lib/backy/railtie.rb +19 -0
  77. data/lib/backy/s3.rb +27 -0
  78. data/lib/backy/s3_list.rb +31 -0
  79. data/lib/backy/s3_load.rb +41 -0
  80. data/lib/backy/s3_save.rb +33 -0
  81. data/lib/backy/version.rb +3 -0
  82. data/lib/backy.rb +30 -0
  83. data/lib/tasks/backy_tasks.rake +84 -0
  84. metadata +291 -0
@@ -0,0 +1,33 @@
1
+ # Files in the config/locales directory are used for internationalization
2
+ # and are automatically loaded by Rails. If you want to use locales other
3
+ # than English, add the necessary files in this directory.
4
+ #
5
+ # To use the locales, use `I18n.t`:
6
+ #
7
+ # I18n.t "hello"
8
+ #
9
+ # In views, this is aliased to just `t`:
10
+ #
11
+ # <%= t("hello") %>
12
+ #
13
+ # To use a different locale, set it with `I18n.locale`:
14
+ #
15
+ # I18n.locale = :es
16
+ #
17
+ # This would use the information in config/locales/es.yml.
18
+ #
19
+ # The following keys must be escaped otherwise they will not be retrieved by
20
+ # the default I18n backend:
21
+ #
22
+ # true, false, on, off, yes, no
23
+ #
24
+ # Instead, surround them with single quotes.
25
+ #
26
+ # en:
27
+ # "true": "foo"
28
+ #
29
+ # To learn more, please read the Rails Internationalization guide
30
+ # available at https://guides.rubyonrails.org/i18n.html.
31
+
32
+ en:
33
+ hello: "Hello world"
@@ -0,0 +1 @@
1
+ 15729cca85c03e01e7b263643b18dfd7
@@ -0,0 +1,43 @@
1
+ # Puma can serve each request in a thread from an internal thread pool.
2
+ # The `threads` method setting takes two numbers: a minimum and maximum.
3
+ # Any libraries that use thread pools should be configured to match
4
+ # the maximum value specified for Puma. Default is set to 5 threads for minimum
5
+ # and maximum; this matches the default thread size of Active Record.
6
+ #
7
+ max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
8
+ min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
9
+ threads min_threads_count, max_threads_count
10
+
11
+ # Specifies the `worker_timeout` threshold that Puma will use to wait before
12
+ # terminating a worker in development environments.
13
+ #
14
+ worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development"
15
+
16
+ # Specifies the `port` that Puma will listen on to receive requests; default is 3000.
17
+ #
18
+ port ENV.fetch("PORT") { 3000 }
19
+
20
+ # Specifies the `environment` that Puma will run in.
21
+ #
22
+ environment ENV.fetch("RAILS_ENV") { "development" }
23
+
24
+ # Specifies the `pidfile` that Puma will use.
25
+ pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
26
+
27
+ # Specifies the number of `workers` to boot in clustered mode.
28
+ # Workers are forked web server processes. If using threads and workers together
29
+ # the concurrency of the application would be max `threads` * `workers`.
30
+ # Workers do not work on JRuby or Windows (both of which do not support
31
+ # processes).
32
+ #
33
+ # workers ENV.fetch("WEB_CONCURRENCY") { 2 }
34
+
35
+ # Use the `preload_app!` method when specifying a `workers` number.
36
+ # This directive tells Puma to first boot the application and load code
37
+ # before forking the application. This takes advantage of Copy On Write
38
+ # process behavior so workers use less memory.
39
+ #
40
+ # preload_app!
41
+
42
+ # Allow puma to be restarted by `bin/rails restart` command.
43
+ plugin :tmp_restart
@@ -0,0 +1,7 @@
1
+ Rails.application.routes.draw do
2
+ resources :posts
3
+ # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
4
+
5
+ # Defines the root path route ("/")
6
+ root "posts#index"
7
+ end
@@ -0,0 +1,6 @@
1
+ # This file is used by Rack-based servers to start the application.
2
+
3
+ require_relative "config/environment"
4
+
5
+ run Rails.application
6
+ Rails.application.load_server
@@ -0,0 +1,10 @@
1
+ class CreatePosts < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :posts do |t|
4
+ t.string :title
5
+ t.text :body
6
+
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,23 @@
1
+ # This file is auto-generated from the current state of the database. Instead
2
+ # of editing this file, please use the migrations feature of Active Record to
3
+ # incrementally modify your database, and then regenerate this schema definition.
4
+ #
5
+ # This file is the source Rails uses to define your schema when running `bin/rails
6
+ # db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
7
+ # be faster and is potentially less error prone than running all of your
8
+ # migrations from scratch. Old migrations may fail to apply correctly if those
9
+ # migrations use external dependencies or application code.
10
+ #
11
+ # It's strongly recommended that you check this file into your version control system.
12
+
13
+ ActiveRecord::Schema[7.0].define(version: 2023_03_30_203226) do
14
+ # These are extensions that must be enabled in order to support this database
15
+ enable_extension "plpgsql"
16
+
17
+ create_table "posts", force: :cascade do |t|
18
+ t.string "title"
19
+ t.text "body"
20
+ t.datetime "created_at", null: false
21
+ t.datetime "updated_at", null: false
22
+ end
23
+ end
@@ -0,0 +1,8 @@
1
+ require "faker"
2
+
3
+ 100.times do
4
+ Post.create(
5
+ title: Faker::Lorem.sentence,
6
+ body: Faker::Lorem.paragraph
7
+ )
8
+ end
File without changes
@@ -0,0 +1,67 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The page you were looking for doesn't exist (404)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ .rails-default-error-page {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ .rails-default-error-page div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ .rails-default-error-page div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ .rails-default-error-page h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ .rails-default-error-page div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body class="rails-default-error-page">
58
+ <!-- This file lives in public/404.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>The page you were looking for doesn't exist.</h1>
62
+ <p>You may have mistyped the address or the page may have moved.</p>
63
+ </div>
64
+ <p>If you are the application owner check the logs for more information.</p>
65
+ </div>
66
+ </body>
67
+ </html>
@@ -0,0 +1,67 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The change you wanted was rejected (422)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ .rails-default-error-page {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ .rails-default-error-page div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ .rails-default-error-page div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ .rails-default-error-page h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ .rails-default-error-page div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body class="rails-default-error-page">
58
+ <!-- This file lives in public/422.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>The change you wanted was rejected.</h1>
62
+ <p>Maybe you tried to change something you didn't have access to.</p>
63
+ </div>
64
+ <p>If you are the application owner check the logs for more information.</p>
65
+ </div>
66
+ </body>
67
+ </html>
@@ -0,0 +1,66 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>We're sorry, but something went wrong (500)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ .rails-default-error-page {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ .rails-default-error-page div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ .rails-default-error-page div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ .rails-default-error-page h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ .rails-default-error-page div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body class="rails-default-error-page">
58
+ <!-- This file lives in public/500.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>We're sorry, but something went wrong.</h1>
62
+ </div>
63
+ <p>If you are the application owner check the logs for more information.</p>
64
+ </div>
65
+ </body>
66
+ </html>
File without changes
File without changes
@@ -0,0 +1 @@
1
+ # See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
File without changes
File without changes
@@ -0,0 +1,11 @@
1
+ require 'forwardable'
2
+
3
+ module Backy
4
+ module AppConfig
5
+ extend Forwardable
6
+
7
+ private
8
+
9
+ def_delegators "Backy.configuration", :app_name, :environment, :log_file
10
+ end
11
+ end
data/lib/backy/cli.rb ADDED
File without changes
@@ -0,0 +1,66 @@
1
+ module Backy
2
+ class Configuration
3
+ attr_writer(
4
+ :pg_host,
5
+ :pg_port,
6
+ :pg_database,
7
+ :pg_username,
8
+ :pg_password,
9
+ :s3_region,
10
+ :s3_access_key,
11
+ :s3_secret,
12
+ :s3_bucket,
13
+ :app_name,
14
+ :environment,
15
+ :log_file
16
+ )
17
+
18
+ def pg_host
19
+ @pg_host ||= ENV["PG_HOST"]
20
+ end
21
+
22
+ def pg_port
23
+ @pg_port ||= ENV["PG_PORT"]
24
+ end
25
+
26
+ def pg_database
27
+ @pg_database ||= ENV["PG_DATABASE"]
28
+ end
29
+
30
+ def pg_username
31
+ @pg_username ||= ENV["PG_USERNAME"]
32
+ end
33
+
34
+ def pg_password
35
+ @pg_password ||= ENV["PG_PASSWORD"]
36
+ end
37
+
38
+ def s3_region
39
+ @s3_region ||= ENV["S3_REGION"]
40
+ end
41
+
42
+ def s3_access_key
43
+ @s3_access_key ||= ENV["S3_ACCESS_KEY"]
44
+ end
45
+
46
+ def s3_secret
47
+ @s3_secret ||= ENV["S3_SECRET"]
48
+ end
49
+
50
+ def s3_bucket
51
+ @s3_bucket ||= ENV["S3_BUCKET"]
52
+ end
53
+
54
+ def app_name
55
+ @app_name ||= "backy"
56
+ end
57
+
58
+ def environment
59
+ @environment ||= "development"
60
+ end
61
+
62
+ def log_file
63
+ @log_file ||= "log/backy.log"
64
+ end
65
+ end
66
+ end
data/lib/backy/db.rb ADDED
@@ -0,0 +1,29 @@
1
+ require 'forwardable'
2
+
3
+ module Backy
4
+ module Db
5
+ extend Forwardable
6
+
7
+ private
8
+
9
+ def_delegator "Backy.configuration", :pg_host, :host
10
+ def_delegator "Backy.configuration", :pg_port, :port
11
+ def_delegator "Backy.configuration", :pg_database, :database
12
+ def_delegator "Backy.configuration", :pg_username, :username
13
+ def_delegator "Backy.configuration", :pg_password, :password
14
+
15
+ def pg_password_env
16
+ password.present? ? "PGPASSWORD='#{password}' " : ""
17
+ end
18
+
19
+ def pg_credentials
20
+ args_string = ""
21
+
22
+ args_string << " -U #{username}" if username.present?
23
+ args_string << " -h #{host}" if host.present?
24
+ args_string << " -p #{port}" if port.present?
25
+
26
+ args_string
27
+ end
28
+ end
29
+ end
data/lib/backy/list.rb ADDED
@@ -0,0 +1,18 @@
1
+ module Backy
2
+ class List
3
+ def call
4
+ locals = Set.new(Dir.glob(dump_wildcard))
5
+ remotes = Set.new(S3List.new.call)
6
+
7
+ (locals + remotes).sort.map do |dump_file|
8
+ OpenStruct.new(local?: dump_file.in?(locals), remote?: dump_file.in?(remotes), dump_file: dump_file)
9
+ end
10
+ end
11
+
12
+ private
13
+
14
+ def dump_wildcard
15
+ PgDump::DUMP_DIR + "/*"
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,39 @@
1
+ module Backy
2
+ class PgDump
3
+ include Db
4
+ include AppConfig
5
+
6
+ DUMP_DIR = "db/dump"
7
+ DUMP_CMD_OPTS = "--no-acl --no-owner --no-subscriptions --no-publications --exclude-table=awsdms_ddl_audit"
8
+
9
+ def call
10
+ FileUtils.mkdir_p(DUMP_DIR)
11
+
12
+ dump_file = "#{DUMP_DIR}/#{database}_#{whoami}@#{hostname}_#{Time.zone.now.strftime("%Y%m%d_%H%M%S")}.sql.gz"
13
+
14
+ cmd = "(#{pg_password_env}pg_dump #{pg_credentials} #{database} #{DUMP_CMD_OPTS} | gzip -9 > #{dump_file}) 2>&1 >> #{log_file}"
15
+
16
+ print "Saving to #{dump_file} ... "
17
+
18
+ if system(cmd)
19
+ puts "done"
20
+ else
21
+ puts "error. See #{log_file}"
22
+
23
+ return
24
+ end
25
+
26
+ dump_file
27
+ end
28
+
29
+ private
30
+
31
+ def hostname
32
+ @hostname ||= `hostname`.strip
33
+ end
34
+
35
+ def whoami
36
+ @whoami ||= `whoami`.strip
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,27 @@
1
+ module Backy
2
+ class PgRestore
3
+ include Db
4
+ include AppConfig
5
+
6
+ def initialize(file_name:)
7
+ @file_name = file_name
8
+ end
9
+
10
+ def call
11
+ terminate_connection_sql = "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '#{database}' AND pid <> pg_backend_pid();"
12
+ cmd = "(#{pg_password_env}psql -c \"#{terminate_connection_sql};\" #{pg_credentials} #{database}; #{pg_password_env}dropdb #{pg_credentials} #{database}; #{pg_password_env}createdb #{pg_credentials} #{database}; gunzip -c #{file_name} | #{pg_password_env}psql #{pg_credentials} -q -d #{database}) 2>&1 >> #{log_file}"
13
+
14
+ print "Restoring #{database} from #{file_name} ... "
15
+
16
+ if system(cmd)
17
+ puts "done"
18
+ else
19
+ puts "error. See #{log_file}"
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :file_name
26
+ end
27
+ end
@@ -0,0 +1,19 @@
1
+ module Backy
2
+ class Railtie < Rails::Railtie
3
+ initializer "railtie.configure_rails_initialization" do
4
+ Backy.configure do |config|
5
+ config.pg_host = ActiveRecord::Base.connection_db_config.configuration_hash[:host]
6
+ config.pg_port = ActiveRecord::Base.connection_db_config.configuration_hash[:port]
7
+ config.pg_database = ActiveRecord::Base.connection_db_config.configuration_hash[:database]
8
+ config.pg_username = ActiveRecord::Base.connection_db_config.configuration_hash[:username]
9
+ config.pg_password = ActiveRecord::Base.connection_db_config.configuration_hash[:password]
10
+ config.app_name = Rails.application.class.name.split("::").first.underscore
11
+ config.environment = Rails.env
12
+ end
13
+ end
14
+
15
+ rake_tasks do
16
+ load "tasks/backy_tasks.rake"
17
+ end
18
+ end
19
+ end
data/lib/backy/s3.rb ADDED
@@ -0,0 +1,27 @@
1
+ require "aws-sdk-s3"
2
+ require 'forwardable'
3
+
4
+ module Backy
5
+ module S3
6
+ extend Forwardable
7
+
8
+ private
9
+
10
+ def_delegator "Backy.configuration", :s3_region, :region
11
+ def_delegator "Backy.configuration", :s3_secret, :secret
12
+ def_delegator "Backy.configuration", :s3_bucket, :bucket
13
+ def_delegator "Backy.configuration", :s3_access_key, :access_key
14
+
15
+ def s3
16
+ @s3 ||= Aws::S3::Client.new(region: region, credentials: s3_credentials)
17
+ end
18
+
19
+ def s3_configured?
20
+ [region, access_key, secret, bucket].all?(&:present?)
21
+ end
22
+
23
+ def s3_credentials
24
+ @credentials ||= Aws::Credentials.new(access_key, secret)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,31 @@
1
+ module Backy
2
+ class S3List
3
+ include S3
4
+
5
+ DEFAULT_PREFIX = "db/dump/"
6
+
7
+ def initialize(prefix: nil)
8
+ @prefix = prefix || DEFAULT_PREFIX
9
+ end
10
+
11
+ def call
12
+ return [] unless s3_configured?
13
+
14
+ response = s3.list_objects(prefix: prefix, bucket: bucket)
15
+
16
+ result = response.contents.map(&:key)
17
+
18
+ while response.next_page?
19
+ response = response.next_page
20
+
21
+ result += response.contents.map(&:key)
22
+ end
23
+
24
+ result.sort
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :prefix
30
+ end
31
+ end
@@ -0,0 +1,41 @@
1
+ module Backy
2
+ class S3Load
3
+ include S3
4
+
5
+ def initialize(file_name:, key: nil)
6
+ @file_name = file_name
7
+ @key = key || file_name
8
+ end
9
+
10
+ def call
11
+ return file_name if File.exist?(file_name)
12
+
13
+ print "Loading #{key} from S3 ... "
14
+
15
+ Tempfile.create(file_name) do |tempfile|
16
+ response_target = tempfile.path
17
+
18
+ begin
19
+ s3.get_object(response_target: response_target, key: key, bucket: bucket)
20
+ FileUtils.mkdir_p(File.dirname(file_name))
21
+ FileUtils.mv(response_target, file_name)
22
+ rescue Aws::S3::Errors::NoSuchKey
23
+ puts "error. No such key #{key}"
24
+ ensure
25
+ if File.exist?(tempfile.path)
26
+ tempfile.close
27
+ File.delete(tempfile.path)
28
+ end
29
+ end
30
+ end
31
+
32
+ puts "done"
33
+
34
+ file_name
35
+ end
36
+
37
+ private
38
+
39
+ attr_reader :key, :file_name
40
+ end
41
+ end