poring_backup 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +34 -0
  4. data/lib/generators/poring_backup/install_generator.rb +13 -0
  5. data/lib/generators/poring_backup/templates/init_backup.rb +28 -0
  6. data/lib/poring_backup.rb +24 -0
  7. data/lib/poring_backup/callback.rb +29 -0
  8. data/lib/poring_backup/database.rb +44 -0
  9. data/lib/poring_backup/databases/postgresql.rb +81 -0
  10. data/lib/poring_backup/logger.rb +45 -0
  11. data/lib/poring_backup/railtie.rb +10 -0
  12. data/lib/poring_backup/setting.rb +64 -0
  13. data/lib/poring_backup/storage.rb +11 -0
  14. data/lib/poring_backup/storages/s3.rb +66 -0
  15. data/lib/poring_backup/version.rb +3 -0
  16. data/lib/tasks/poring_backup_tasks.task +14 -0
  17. data/test/dummy/README.rdoc +28 -0
  18. data/test/dummy/Rakefile +6 -0
  19. data/test/dummy/app/assets/javascripts/application.js +13 -0
  20. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  21. data/test/dummy/app/controllers/application_controller.rb +5 -0
  22. data/test/dummy/app/helpers/application_helper.rb +2 -0
  23. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  24. data/test/dummy/bin/bundle +3 -0
  25. data/test/dummy/bin/rails +4 -0
  26. data/test/dummy/bin/rake +4 -0
  27. data/test/dummy/bin/setup +29 -0
  28. data/test/dummy/config.ru +4 -0
  29. data/test/dummy/config/application.rb +26 -0
  30. data/test/dummy/config/boot.rb +5 -0
  31. data/test/dummy/config/database.sample.yml +16 -0
  32. data/test/dummy/config/database.travis.yml +18 -0
  33. data/test/dummy/config/database.yml +16 -0
  34. data/test/dummy/config/environment.rb +5 -0
  35. data/test/dummy/config/environments/development.rb +41 -0
  36. data/test/dummy/config/environments/production.rb +79 -0
  37. data/test/dummy/config/environments/test.rb +42 -0
  38. data/test/dummy/config/initializers/assets.rb +11 -0
  39. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  40. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  41. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  42. data/test/dummy/config/initializers/inflections.rb +16 -0
  43. data/test/dummy/config/initializers/mime_types.rb +4 -0
  44. data/test/dummy/config/initializers/poring_backup.rb +23 -0
  45. data/test/dummy/config/initializers/session_store.rb +3 -0
  46. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  47. data/test/dummy/config/locales/en.yml +23 -0
  48. data/test/dummy/config/routes.rb +56 -0
  49. data/test/dummy/config/secrets.sample.yml +22 -0
  50. data/test/dummy/config/secrets.yml +22 -0
  51. data/test/dummy/db/schema.rb +19 -0
  52. data/test/dummy/log/backup_development.log +139 -0
  53. data/test/dummy/log/backup_test.log +27 -0
  54. data/test/dummy/log/development.log +3 -0
  55. data/test/dummy/log/test.log +1524 -0
  56. data/test/dummy/public/404.html +67 -0
  57. data/test/dummy/public/422.html +67 -0
  58. data/test/dummy/public/500.html +66 -0
  59. data/test/dummy/public/favicon.ico +0 -0
  60. data/test/dummy/spec/lib/database_spec.rb +46 -0
  61. data/test/dummy/spec/lib/databases/postgresql_spec.rb +85 -0
  62. data/test/dummy/spec/lib/setting_spec.rb +62 -0
  63. data/test/dummy/spec/lib/storage_spec.rb +15 -0
  64. data/test/dummy/spec/lib/storages/s3_spec.rb +43 -0
  65. data/test/dummy/spec/rails_helper.rb +69 -0
  66. data/test/dummy/spec/spec_helper.rb +87 -0
  67. data/test/poring_backup_test.rb +7 -0
  68. data/test/test_helper.rb +19 -0
  69. metadata +219 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9443a747e4f2589aa9c81ac0d0968359070e21eb
4
+ data.tar.gz: 557092c3199de2e150dcfef3b0afabd2655e0fb1
5
+ SHA512:
6
+ metadata.gz: 2b3298b1c5ffb8db11edcb4919a0c2b3c422ea01cf0b01cebbff4b701d2a1b7e8a04350a1f71415ead2fa9cda8ee0ac46372dfaeeb5c62c5ed25f8414b00b3f9
7
+ data.tar.gz: 43c5429b16dde4ea30f1137d19f20a843a5a8f1028cc451833e4ec11c3c269d060eff27fe3a41d2fced98d94f76aff71a3cac859f2249dcc93f7e52429b994a3
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2015 PiYa
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,34 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'PoringBackup'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+
18
+
19
+
20
+
21
+
22
+ Bundler::GemHelper.install_tasks
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'lib'
28
+ t.libs << 'test'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = false
31
+ end
32
+
33
+
34
+ task default: :test
@@ -0,0 +1,13 @@
1
+ require 'rails/generators/base'
2
+
3
+ module PoringBackup
4
+ module Generators
5
+ class InstallGenerator < Rails::Generators::Base
6
+ source_root File.expand_path('../templates', __FILE__)
7
+
8
+ def copy_initializer_file
9
+ copy_file "init_backup.rb", "config/initializers/poring_backup.rb"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,28 @@
1
+
2
+ # run backup `rake poring_backup:perform`
3
+
4
+ PoringBackup.config do
5
+
6
+ # before do
7
+ # #do somethings before backup
8
+ # end
9
+
10
+ # after do
11
+ # #do somethings after backup
12
+ # end
13
+
14
+ # database :PostgreSQL do
15
+ # database 'database_name'
16
+ # username 'username'
17
+ # password 'password'
18
+ # end
19
+
20
+ # store_with :S3 do
21
+ # access_key_id 'access_key_id'
22
+ # secret_access_key 'secret_access_key'
23
+ # bucket 'bucket_name'
24
+ # region 'region'
25
+ # path 'your/path'
26
+ # end
27
+
28
+ end
@@ -0,0 +1,24 @@
1
+
2
+ require 'aws-sdk'
3
+ require 'logging'
4
+
5
+ require 'poring_backup/setting'
6
+ require 'poring_backup/logger'
7
+
8
+ require 'poring_backup/database'
9
+ require 'poring_backup/databases/postgresql'
10
+
11
+ require 'poring_backup/storage'
12
+ require 'poring_backup/storages/s3'
13
+
14
+ # tasks
15
+ require "poring_backup/railtie" if defined?(Rails)
16
+
17
+ module PoringBackup
18
+ class << self
19
+ attr_reader :model
20
+ def config &block
21
+ @model = Setting.new(&block)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,29 @@
1
+ module PoringBackup
2
+ module Settings
3
+ module Callback
4
+
5
+ def before &block
6
+ @before_actions << block
7
+ end
8
+
9
+ def after &block
10
+ @after_actions << block
11
+ end
12
+
13
+ private
14
+ def before_backup
15
+ unless @before_actions.empty?
16
+ PoringBackup.logger.info "----- before processing..."
17
+ @before_actions.each { |action| action.call(PoringBackup.logger) }
18
+ end
19
+ end
20
+
21
+ def after_backup
22
+ unless @after_actions.empty?
23
+ PoringBackup.logger.info "----- after processing..."
24
+ @after_actions.each { |action| action.call(PoringBackup.logger) }
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,44 @@
1
+ module PoringBackup
2
+ class Database
3
+
4
+ attr_reader :setting
5
+ attr_reader :file, :tmp_file_path, :file_path
6
+ attr_reader :path, :tmp_dir, :file_dir
7
+ attr_reader :created_at
8
+
9
+ def initialize setting, &block
10
+ @created_at = setting.created_at
11
+ @setting = setting
12
+ @path ||= 'db_backups'
13
+ @file ||= 'db_backup.psql'
14
+
15
+ gen_file_dir
16
+ gen_file_path
17
+ gen_tmp_dir
18
+ gen_tmp_file_path
19
+ end
20
+
21
+ def backup
22
+ FileUtils.mkdir_p(tmp_dir)
23
+ end
24
+
25
+ def clear_tmp!
26
+ FileUtils.rm_rf(tmp_file_path)
27
+ end
28
+
29
+ private
30
+ def gen_file_dir
31
+ @file_dir = "#{path}/#{created_at}"
32
+ end
33
+ def gen_file_path
34
+ @file_path = "#{file_dir}/#{file}"
35
+ end
36
+
37
+ def gen_tmp_dir
38
+ @tmp_dir = "#{setting.tmp_dir}/#{file_dir}"
39
+ end
40
+ def gen_tmp_file_path
41
+ @tmp_file_path ||= "#{tmp_dir}/#{file}"
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,81 @@
1
+ module PoringBackup
2
+ module Databases
3
+ class PostgreSQL < Database
4
+
5
+ def initialize setting, &block
6
+ @database = nil
7
+ @host = 'localhost'
8
+ @port = nil
9
+ @username = nil
10
+ @password = nil
11
+
12
+ instance_eval(&block) if block_given?
13
+ @file = "#{@database}.pgsql"
14
+ super
15
+ end
16
+
17
+ def backup
18
+ PoringBackup.logger.info "PostgreSQL backup processing"
19
+ super
20
+ begin
21
+ system db_dump
22
+ PoringBackup.logger.info "#{' '*18}success"
23
+ rescue => e
24
+ PoringBackup.logger.warn "#{' '*18}failed!"
25
+ PoringBackup.logger.debug "#{' '*18}tmp_file: #{tmp_file_path}"
26
+ PoringBackup.logger.debug "#{' '*18}errors => #{e}"
27
+ end
28
+ PoringBackup.logger.info "#{' '*18}finished"
29
+ end
30
+
31
+ def restore
32
+ #psql -U {user-name} -d {desintation_db} -f {dumpfilename.sql}
33
+ #psql -U <username> -d <dbname> -1 -f <filename>.sql
34
+ #pg_restore -U <username> -d <dbname> -1 -f <filename>.dump
35
+ end
36
+
37
+ def database name
38
+ @database = name
39
+ end
40
+
41
+ def host name
42
+ @host = name
43
+ end
44
+
45
+ def port number
46
+ @port = number
47
+ end
48
+
49
+ def username name
50
+ @username = name
51
+ end
52
+
53
+ def password password
54
+ @password = password
55
+ end
56
+
57
+ def db_dump
58
+ "pg_dump #{connection_options} #{general_options} #{@database}"
59
+ end
60
+
61
+ private
62
+ def connection_options
63
+ options = ''
64
+ options << "--host=#{@host || 'localhost'}"
65
+ options << " --port=#{@port}" if @port
66
+ options << " --username=#{@username}" if @username
67
+ # options << " --no-password"
68
+ # options << " --password"
69
+ options
70
+ end
71
+
72
+ def general_options
73
+ options = ''
74
+ options << "--file=#{tmp_file_path}"
75
+ options << ' --compress=9'
76
+ options
77
+ end
78
+ end
79
+ end
80
+
81
+ end
@@ -0,0 +1,45 @@
1
+ module PoringBackup
2
+ class << self
3
+ attr_reader :logger
4
+ end
5
+ module Logger
6
+ class << self
7
+ def log_file_path
8
+ file_name = Rails.env.product? ? 'backup' : "backup_#{Rails.env}"
9
+ "log/#{file_name}.log"
10
+ end
11
+ end
12
+
13
+ Logging.color_scheme( 'bright',
14
+ :levels => {
15
+ :info => :green,
16
+ :warn => :yellow,
17
+ :error => :red,
18
+ :fatal => [:white, :on_red]
19
+ },
20
+ :date => :blue,
21
+ :logger => :cyan,
22
+ :message => :magenta
23
+ )
24
+
25
+ Logging.appenders.stdout(
26
+ 'stdout',
27
+ :layout => Logging.layouts.pattern(
28
+ :pattern => '[%d] %-5l %c: %m\n',
29
+ :color_scheme => 'bright'
30
+ )
31
+ )
32
+
33
+ PoringBackup.instance_variable_set("@logger", Logging.logger['PoringBackup::Log'])
34
+ PoringBackup.logger.add_appenders(
35
+ Logging.appenders.stdout,
36
+ Logging.appenders.file(:poring_backup,
37
+ filename: log_file_path,
38
+ # layout: Logging.layouts.pattern(
39
+ # :pattern => '[%d] %-5l : %m\n',
40
+ # :color_scheme => 'bright'
41
+ # )
42
+ )
43
+ )
44
+ end
45
+ end
@@ -0,0 +1,10 @@
1
+ require 'poring_backup'
2
+ require 'rails'
3
+
4
+ module PoringBackup
5
+ class Railtie < Rails::Railtie
6
+ rake_tasks do
7
+ import File.expand_path('../../tasks/poring_backup_tasks.task', __FILE__)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,64 @@
1
+ require 'poring_backup/callback'
2
+
3
+ module PoringBackup
4
+ class Setting
5
+ include Settings::Callback
6
+
7
+ attr_reader :before_actions, :after_actions
8
+ attr_reader :dir, :tmp_dir
9
+ attr_reader :databases, :storages
10
+ attr_reader :created_at
11
+
12
+ def initialize &block
13
+ @created_at = Time.now.strftime("%Y.%m.%d.%H.%M.%S")
14
+ @before_actions = []
15
+ @after_actions = []
16
+ @dir = 'poring_backups'
17
+ @tmp_dir = "tmp/poring_backups"
18
+ @databases = []
19
+ @storages = []
20
+ instance_eval(&block) if block_given?
21
+ end
22
+
23
+ def database model, &block
24
+ @databases << class_from_scope(Databases, model).new(self, &block)
25
+ end
26
+
27
+ def store_with model, &block
28
+ @storages << class_from_scope(Storages, model).new(self, &block)
29
+ end
30
+
31
+ def perform!
32
+ PoringBackup.logger.info "PoringBackup Start..."
33
+ before_backup
34
+ backup!
35
+ store!
36
+ clear_tmp!
37
+ after_backup
38
+ PoringBackup.logger.info "PoringBackup Done"
39
+ end
40
+
41
+ def clear_tmp!
42
+ FileUtils.rm_rf(tmp_dir)
43
+ PoringBackup.logger.debug "clear tmp directory"
44
+ end
45
+
46
+ private
47
+ def class_from_scope scope, klass
48
+ "#{scope}::#{klass}".constantize
49
+ end
50
+
51
+ def backup!
52
+ PoringBackup.logger.info "--------- Backup ----------"
53
+ databases.each(&:backup)
54
+ end
55
+
56
+ def store!
57
+ PoringBackup.logger.info "----------- Store ---------"
58
+ storages.each(&:upload)
59
+ end
60
+
61
+
62
+
63
+ end
64
+ end
@@ -0,0 +1,11 @@
1
+ module PoringBackup
2
+ class Storage
3
+
4
+ attr_reader :setting
5
+
6
+ def initialize setting, &block
7
+ @setting = setting
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,66 @@
1
+ module PoringBackup
2
+ module Storages
3
+ class S3 < Storage
4
+
5
+ attr_reader :s3, :bucket_object
6
+
7
+ def initialize setting, &block
8
+ super
9
+ instance_eval(&block) if block_given?
10
+ @s3 = aws_resource
11
+ @bucket_object = @s3.bucket(@bucket)
12
+ end
13
+
14
+ def access_key_id key
15
+ @access_key_id = key
16
+ end
17
+
18
+ def secret_access_key key
19
+ @secret_access_key = key
20
+ end
21
+
22
+ def bucket name
23
+ @bucket = name
24
+ end
25
+
26
+ def region name
27
+ @region = name
28
+ end
29
+
30
+ def path name
31
+ @path = name
32
+ end
33
+
34
+ def upload
35
+ PoringBackup.logger.info "S3 processing"
36
+ setting.databases.each do |db|
37
+ s3_path = "#{@path}/#{db.file_path}"
38
+ object = @bucket_object.object(s3_path)
39
+ success = object.upload_file(db.tmp_file_path)
40
+ if success
41
+ PoringBackup.logger.info "#{' '*3}uploaded: #{s3_path}"
42
+ else
43
+ PoringBackup.logger.warn "#{' '*3}uploaded failure: #{db.tmp_file_path}"
44
+ end
45
+ end
46
+ PoringBackup.logger.info "#{' '*3}finished"
47
+ end
48
+
49
+ private
50
+ def aws_resource
51
+ @aws_resource ||= Aws::S3::Resource.new(client: aws_client)
52
+ end
53
+ def aws_client
54
+ @aws_client ||= Aws::S3::Client.new(
55
+ region: @region,
56
+ credentials: aws_credentials
57
+ )
58
+ end
59
+
60
+ def aws_credentials
61
+ @aws_credentials ||= Aws::Credentials.new(@access_key_id, @secret_access_key)
62
+ end
63
+
64
+ end
65
+ end
66
+ end