easy_backup 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .idea
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in easy_backup.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,35 @@
1
+ ## DSL Example
2
+
3
+ ``` rb
4
+ EasyBackup.config do
5
+
6
+ save PostgreSQL do
7
+ host 'localhost'
8
+ port 5432
9
+ database 'db_production'
10
+ username 'user_prod'
11
+ password 'password'
12
+ zip
13
+ end
14
+
15
+ save FileSystem do
16
+ folder 'c:/resources'
17
+ file 'c:/data/file.txt'
18
+ zip 'data.zip'
19
+ end
20
+
21
+ into FileSystem do
22
+ folder lambda { "c:/backups/#{Time.now.strftime('%Y%m%d%H%M%S')}" }
23
+ end
24
+
25
+ into SFTP do
26
+ host 'remote'
27
+ username 'user_sftp'
28
+ password 'password'
29
+ folder "backups/#{Time.now.strftime('%Y%m%d%H%M%S')}"
30
+ end
31
+
32
+ every 1.day, from: 'today at 22:30'
33
+
34
+ end
35
+ ```
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "easy_backup/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "easy_backup"
7
+ s.version = EasyBackup::VERSION
8
+ s.authors = ["Gabriel Naiman"]
9
+ s.email = ["gabynaiman@gmail.com"]
10
+ s.homepage = "https://github.com/gabynaiman/easy_backup"
11
+ s.summary = "Easy DSL to program backups"
12
+ s.description = "Easy DSL to program backups"
13
+
14
+ s.rubyforge_project = "easy_backup"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency 'rubyzip'
22
+ s.add_dependency 'net-sftp'
23
+ s.add_dependency 'active_support'
24
+ s.add_dependency 'i18n'
25
+ s.add_dependency 'chronic'
26
+ s.add_dependency 'rufus-scheduler'
27
+
28
+ s.add_development_dependency 'sequel'
29
+ s.add_development_dependency 'pg'
30
+ s.add_development_dependency "rspec"
31
+ end
@@ -0,0 +1,81 @@
1
+ require 'open3'
2
+ require 'zip/zip'
3
+
4
+ include Zip
5
+
6
+ module EasyBackup
7
+ module Adapter
8
+ module Db
9
+ class PostgreSQL
10
+
11
+ def host(host=nil)
12
+ host ? @host = host : (@host || 'localhost')
13
+ end
14
+
15
+ def database(database=nil)
16
+ database ? @database = database : @database
17
+ end
18
+
19
+ def username(username=nil)
20
+ username ? @username = username : (@username || 'postgres')
21
+ end
22
+
23
+ def password(password=nil)
24
+ password ? @password = password : @password
25
+ end
26
+
27
+ def port(port=nil)
28
+ port ? @port = port : (@port || 5432)
29
+ end
30
+
31
+ def dump_file(file_name=nil)
32
+ if file_name
33
+ @dump_file = file_name
34
+ else
35
+ if @dump_file
36
+ @dump_file.is_a?(Proc) ? @dump_file.call : @dump_file
37
+ else
38
+ "#{database}_#{Time.now.strftime('%Y%m%d%H%M%S')}.sql"
39
+ end
40
+ end
41
+ end
42
+
43
+ def zip_file(file_name=nil)
44
+ file_name ? @zip_file = file_name : @zip_file
45
+ end
46
+
47
+ def zip
48
+ zip_file "#{File.basename(dump_file, '.*')}.zip"
49
+ end
50
+
51
+ def send_to(storages)
52
+ FileUtils.mkpath File.dirname(path_to(dump_file)) unless Dir.exist? File.dirname(path_to(dump_file))
53
+
54
+ EasyBackup.logger.info "[PostgreSQL] Dump postgres://#{username}:*****@#{host}:#{port}/#{database}\n#{' '*15}to #{path_to(dump_file)}"
55
+
56
+ Open3.popen3 "pg_dump -h #{host} -p #{port} -U #{username} #{database} > #{path_to(dump_file)}" do |i, o, e, t|
57
+ if t.value.success?
58
+ if zip_file
59
+ EasyBackup.logger.info "#{(' '*14)}zip #{path_to(zip_file)}"
60
+ ZipFile.open(path_to(zip_file), ZipFile::CREATE) { |zip| zip.add dump_file, path_to(dump_file) }
61
+ end
62
+ storages.each { |s| s.save path_to(zip_file ? zip_file : dump_file) }
63
+ else
64
+ EasyBackup.logger.error "[PostgreSQL] Error: #{e.readlines.join}"
65
+ end
66
+ end
67
+
68
+ FileUtils.rm path_to(dump_file) if File.exist? path_to(dump_file)
69
+ FileUtils.rm path_to(zip_file) if zip_file && File.exist?(path_to(zip_file))
70
+ end
71
+
72
+ private
73
+
74
+ def path_to(file_name)
75
+ "#{EasyBackup.tmp_path}/pg_dump/#{file_name}"
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+
@@ -0,0 +1,83 @@
1
+ module EasyBackup
2
+ module Adapter
3
+ class FileSystem
4
+
5
+ def initialize
6
+ @folders = []
7
+ @files = []
8
+ end
9
+
10
+ def folder(path)
11
+ @folders << path
12
+ end
13
+
14
+ def folders
15
+ @folders.map { |f| f.is_a?(Proc) ? f.call : f }
16
+ end
17
+
18
+ def file(file_name)
19
+ @files << file_name
20
+ end
21
+
22
+ def files
23
+ @files.map { |f| f.is_a?(Proc) ? f.call : f }
24
+ end
25
+
26
+ def zip(file_name)
27
+ @zip_file = file_name
28
+ end
29
+
30
+ def zip_file
31
+ @zip_file.is_a?(Proc) ? @zip_file.call : @zip_file
32
+ end
33
+
34
+ def send_to(storages)
35
+ if zip_file
36
+ EasyBackup.logger.info "[FileSystem] Zip #{zip_path(zip_file)}"
37
+ FileUtils.mkpath File.dirname(zip_path(zip_file))
38
+ ZipFile.open(zip_path(zip_file), ZipFile::CREATE) do |zip|
39
+ (files | folders).each do |resource|
40
+ if Dir.exist? resource
41
+ EasyBackup.logger.info "#{' '*13}add #{resource}"
42
+ Dir["#{resource}/**/**"].each do |r|
43
+ EasyBackup.logger.info "#{' '*13}add #{r}" unless Dir.exist? r
44
+ zip.add "#{File.basename(resource)}/#{r.gsub("#{resource}/", '')}", r
45
+ end
46
+ else
47
+ EasyBackup.logger.info "#{' '*13}add #{resource}"
48
+ zip.add File.basename(resource), resource
49
+ end
50
+ end
51
+ end
52
+ storages.each { |s| s.save zip_path(zip_file) }
53
+ FileUtils.rm zip_path(zip_file)
54
+ else
55
+ (files | folders).each do |resource|
56
+ storages.each { |s| s.save resource } if File.exist? resource
57
+ end
58
+ end
59
+ end
60
+
61
+ def save(resource)
62
+ folders.each do |folder|
63
+ EasyBackup.logger.info "[FileSystem] Saving #{resource}\n#{' '*15}into #{folder}"
64
+
65
+ FileUtils.mkpath folder unless Dir.exist? folder
66
+ if Dir.exist? resource
67
+ FileUtils.cp_r resource, "#{folder}/#{File.basename(resource)}"
68
+ else
69
+ FileUtils.cp resource, "#{folder}/#{File.basename(resource)}"
70
+ end
71
+ end
72
+ end
73
+
74
+ private
75
+
76
+ def zip_path(file_name)
77
+ "#{EasyBackup.tmp_path}/zip/#{file_name}"
78
+ end
79
+
80
+ end
81
+ end
82
+ end
83
+
@@ -0,0 +1,36 @@
1
+ require 'net/sftp'
2
+
3
+ module EasyBackup
4
+ module Adapter
5
+ class SFTP
6
+ def host(host=nil)
7
+ host ? @host = host : @host
8
+ end
9
+
10
+ def username(username=nil)
11
+ username ? @username = username : @username
12
+ end
13
+
14
+ def password(password=nil)
15
+ password ? @password = password : @password
16
+ end
17
+
18
+ def folder(folder=nil)
19
+ if folder
20
+ @folder = folder
21
+ else
22
+ @folder.is_a?(Proc) ? @folder.call : @folder
23
+ end
24
+ end
25
+
26
+ def save(resource)
27
+ Net::SFTP.start(host, username, :password => password) do |sftp|
28
+ EasyBackup.logger.info "[SFTP] Saving #{resource}\n#{' '*9}into #{host} | #{username} | #{folder}"
29
+
30
+ sftp.mkpath! folder
31
+ sftp.upload! resource, "#{folder}/#{File.basename(resource)}"
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,46 @@
1
+ require 'rufus-scheduler'
2
+
3
+ module EasyBackup
4
+
5
+ class Base
6
+
7
+ def initialize(interval=EasyBackup.interval, &block)
8
+ @configurations = {}
9
+ instance_eval &block
10
+ @scheduler = Rufus::Scheduler.start_new frequency: interval
11
+ schedule
12
+ end
13
+
14
+ def [](name)
15
+ @configurations[name]
16
+ end
17
+
18
+ def start
19
+ @scheduler.join
20
+ end
21
+
22
+ private
23
+
24
+ def []=(name, value)
25
+ @configurations[name] = value
26
+ end
27
+
28
+ def config(name=:default, &block)
29
+ self[name] = Configuration.new do
30
+ instance_eval &block
31
+ end
32
+ end
33
+
34
+ def schedule
35
+ @configurations.each do |name, c|
36
+ c.frequencies.each do |f|
37
+ @scheduler.every f.interval, first_at: f.from do
38
+ EasyBackup.logger.info "[EasyBackup] Starting #{name} at #{Time.now}"
39
+ Runner.run c
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,27 @@
1
+ module EasyBackup
2
+ class Configuration
3
+ attr_reader :resources, :storages, :frequencies
4
+
5
+ def initialize(&block)
6
+ @resources = []
7
+ @storages = []
8
+ @frequencies = []
9
+ instance_eval &block if block_given?
10
+ end
11
+
12
+ def save(adapter_class, &block)
13
+ resources << adapter_class.new
14
+ resources.last.instance_eval &block if block_given?
15
+ end
16
+
17
+ def into(adapter_class, &block)
18
+ storages << adapter_class.new
19
+ storages.last.instance_eval &block if block_given?
20
+ end
21
+
22
+ def every(interval, options={})
23
+ frequencies << Frequency.new(interval, options)
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,13 @@
1
+ module Net
2
+ module SFTP
3
+ class Session
4
+ def mkpath!(path)
5
+ path.split('/').inject(nil) do |previous, relative|
6
+ current = previous ? "#{previous}/#{relative}" : relative
7
+ mkdir! current if dir.glob('.', current).empty?
8
+ current
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require 'chronic'
2
+
3
+ module EasyBackup
4
+ class Frequency
5
+ attr_accessor :interval, :from
6
+
7
+ def initialize(interval, options={})
8
+ @interval = interval
9
+ @from = options[:from].is_a?(String) ? Chronic.parse(options[:from]) : options[:from]
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ module EasyBackup
2
+ class Runner
3
+ def self.run(configuration)
4
+ configuration.resources.each do |resource|
5
+ resource.send_to configuration.storages
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module EasyBackup
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,59 @@
1
+ require 'logger'
2
+ require 'active_support/all'
3
+
4
+ require 'easy_backup/version'
5
+ require 'easy_backup/base'
6
+ require 'easy_backup/configuration'
7
+ require 'easy_backup/frequency'
8
+ require 'easy_backup/runner'
9
+
10
+ require 'easy_backup/adapter/file_system'
11
+ require 'easy_backup/adapter/sftp'
12
+ require 'easy_backup/adapter/db/postgre_sql'
13
+
14
+ require 'easy_backup/extension/net_sftp_session'
15
+
16
+
17
+ include EasyBackup
18
+ include EasyBackup::Adapter
19
+ include EasyBackup::Adapter::Db
20
+
21
+ module EasyBackup
22
+
23
+ def self.logger
24
+ @@logger ||= Logger.new($stdout)
25
+ end
26
+
27
+ def self.logger=(logger)
28
+ @@logger = logger
29
+ end
30
+
31
+ def self.interval
32
+ @@interval ||= 1.minute
33
+ end
34
+
35
+ def self.interval=(interval)
36
+ @@interval = interval
37
+ end
38
+
39
+ def self.tmp_path
40
+ @tmp_path ||= "#{ENV['tmp'].gsub('\\', '/')}/easy_backup"
41
+ end
42
+
43
+ def self.tmp_path=(path)
44
+ @tmp_path = path
45
+ end
46
+
47
+ def self.config(name=:default, &block)
48
+ Base.new do
49
+ config name, &block
50
+ end
51
+ end
52
+
53
+ def self.load(config_file)
54
+ Base.new do
55
+ eval File.open(config_file, 'r') { |f| f.readlines.join("\n") }
56
+ end
57
+ end
58
+
59
+ end
data/spec/config.yaml ADDED
@@ -0,0 +1,11 @@
1
+ postgresql:
2
+ host: localhost
3
+ port: 5432
4
+ database: easy_backup_db
5
+ username: postgres
6
+ password: password
7
+
8
+ sftp:
9
+ host: 10.16.229.132
10
+ username: keepcon_backup
11
+ password: WNzxIMPwIuXGqV
@@ -0,0 +1,131 @@
1
+ require 'spec_helper'
2
+ require 'JSON'
3
+ require 'yaml'
4
+ require 'sequel'
5
+ require 'zip/zip'
6
+ require 'net/sftp'
7
+
8
+ describe Runner, '-> Execution' do
9
+
10
+ after :all do
11
+ FileUtils.rm_rf BACKUP_PATH
12
+ end
13
+
14
+ it 'Backup a file to file system' do
15
+ config = Configuration.new do
16
+ save FileSystem do
17
+ file "#{DATA_PATH}/sample.json"
18
+ end
19
+ into FileSystem do
20
+ folder "#{BACKUP_PATH}/#{Time.now.strftime('%Y%m%d%H%M%S%L')}"
21
+ end
22
+ end
23
+
24
+ Runner.run config
25
+
26
+ file = "#{config.storages.first.folders.first}/sample.json"
27
+ File.exist?(file).should be_true
28
+ data = File.open(file, 'r') { |f| JSON.parse f.readlines.join }
29
+ data['id'].should be 1234
30
+ data['name'].should eq 'sample'
31
+ end
32
+
33
+ it 'Backup folder to file system' do
34
+ config = Configuration.new do
35
+ save FileSystem do
36
+ folder "#{DATA_PATH}/txt"
37
+ end
38
+ into FileSystem do
39
+ folder "#{BACKUP_PATH}/#{Time.now.strftime('%Y%m%d%H%M%S%L')}"
40
+ end
41
+ end
42
+
43
+ Runner.run config
44
+
45
+ path = "#{config.storages.first.folders.first}/txt"
46
+ (1..2).each do |i|
47
+ file = "#{path}/#{i}/text#{i}.txt"
48
+ File.exist?(file).should be_true
49
+ File.open(file, 'r') { |f| f.gets.should eq "Text file #{i}" }
50
+ end
51
+ end
52
+
53
+ it 'Backup file and folder zipped to file system' do
54
+ zip_file = "data_#{Time.now.strftime('%Y%m%d%H%M%S%L')}.zip"
55
+ backup_path = "#{BACKUP_PATH}/#{Time.now.strftime('%Y%m%d%H%M%S%L')}"
56
+
57
+ config = Configuration.new do
58
+ save FileSystem do
59
+ folder "#{DATA_PATH}/txt"
60
+ folder "#{DATA_PATH}/sample.json"
61
+ zip zip_file
62
+ end
63
+ into FileSystem do
64
+ folder backup_path
65
+ end
66
+ end
67
+
68
+ Runner.run config
69
+
70
+ File.exists?("#{backup_path}/#{zip_file}").should be_true
71
+
72
+ Zip::ZipFile.open("#{backup_path}/#{zip_file}") do |zip|
73
+ zip.find_entry('sample.json').should_not be_nil
74
+ zip.find_entry('txt/1/text1.txt').should_not be_nil
75
+ zip.find_entry('txt/2/text2.txt').should_not be_nil
76
+ end
77
+ end
78
+
79
+ it 'Backup PostgreSQL to file system' do
80
+ PostgreSQLHelper.create_db
81
+ db = PostgreSQLHelper.configuration
82
+ backup_path = "#{BACKUP_PATH}/#{Time.now.strftime('%Y%m%d%H%M%S%L')}"
83
+
84
+ config = Configuration.new do
85
+ save PostgreSQL do
86
+ host db['host']
87
+ database db['database']
88
+ port db['port']
89
+ username db['username']
90
+ password db['password']
91
+ zip
92
+ end
93
+ into FileSystem do
94
+ folder backup_path
95
+ end
96
+ end
97
+
98
+ Runner.run config
99
+
100
+ PostgreSQLHelper.drop_db
101
+
102
+ Dir["#{backup_path}/#{db['database']}_*.zip"].should have(1).items
103
+ Zip::ZipFile.foreach(Dir["#{backup_path}/#{db['database']}_*.zip"].first) do |entry|
104
+ entry.get_input_stream.read.should include 'PostgreSQL database dump'
105
+ end
106
+ end
107
+
108
+ it 'Backup a file to sftp' do
109
+ storage = ConfigHelper.get 'sftp'
110
+ backup_path = "tmp/#{Time.now.strftime('%Y%m%d%H%M%S%L')}"
111
+ config = Configuration.new do
112
+ save FileSystem do
113
+ file "#{DATA_PATH}/txt/1/text1.txt"
114
+ end
115
+ into SFTP do
116
+ host storage['host']
117
+ username storage['username']
118
+ password storage['password']
119
+ folder backup_path
120
+ end
121
+ end
122
+
123
+ Runner.run config
124
+
125
+ Net::SFTP.start(storage['host'], storage['username'], :password => storage['password']) do |sftp|
126
+ sftp.dir.glob(backup_path, 'text1.txt').should have(1).item
127
+ sftp.file.open("#{backup_path}/text1.txt", 'r') { |f| f.gets.should eq 'Text file 1' }
128
+ end
129
+ end
130
+
131
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe EasyBackup, '-> Scheduled run' do
4
+
5
+ after :all do
6
+ FileUtils.rm_rf BACKUP_PATH
7
+ end
8
+
9
+ it 'Run scheduled backup' do
10
+ test_path = "#{BACKUP_PATH}/#{Time.now.to_f}"
11
+
12
+ EasyBackup::Base.new 0.5 do
13
+ config :test_backup do
14
+ save FileSystem do
15
+ file "#{DATA_PATH}/txt/1/text1.txt"
16
+ end
17
+ into FileSystem do
18
+ folder lambda { "#{test_path}/#{Time.now.strftime('%Y-%m-%d %H_%M_%S_%L')}" }
19
+ end
20
+ every 0.5, from: 1.second.from_now
21
+ end
22
+ end
23
+
24
+ sleep(2)
25
+
26
+ Dir.glob("#{test_path}/*").should have(2).items
27
+ end
28
+
29
+ end
@@ -0,0 +1,20 @@
1
+ config :test_backup do
2
+
3
+ save PostgreSQL do
4
+ host 'localhost'
5
+ database 'test_db'
6
+ username 'user'
7
+ password 'password'
8
+ end
9
+
10
+ save FileSystem do
11
+ folder 'c:/data'
12
+ end
13
+
14
+ into FileSystem do
15
+ folder 'c:/backup'
16
+ end
17
+
18
+ every 1.day, from: 'today at 22:30'
19
+
20
+ end
@@ -0,0 +1,4 @@
1
+ {
2
+ "id": 1234,
3
+ "name": "sample"
4
+ }
@@ -0,0 +1 @@
1
+ Text file 1
@@ -0,0 +1 @@
1
+ Text file 2
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'easy_backup'
4
+
5
+ DATA_PATH = "#{File.dirname(__FILE__)}/files/data"
6
+ BACKUP_PATH = "#{ENV['tmp'].gsub('\\', '/')}/easy_backup/backups"
7
+
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+
12
+ end
@@ -0,0 +1,100 @@
1
+ require 'spec_helper'
2
+
3
+ describe Configuration, '-> Specification' do
4
+
5
+ it 'Save file system' do
6
+ config = Configuration.new
7
+
8
+ config.resources.should be_empty
9
+
10
+ config.save FileSystem do
11
+ folder 'c:/folder1'
12
+ file 'c:/folder2/file.txt'
13
+ end
14
+
15
+ config.save FileSystem do
16
+ folder 'c:/folder3'
17
+ folder 'c:/folder4'
18
+ folder 'c:/folder5'
19
+ end
20
+
21
+ config.resources.should have(2).items
22
+
23
+ config.resources[0].should be_a FileSystem
24
+ config.resources[0].folders.should have(1).items
25
+ config.resources[0].folders.should include 'c:/folder1'
26
+ config.resources[0].files.should have(1).items
27
+ config.resources[0].files.should include 'c:/folder2/file.txt'
28
+
29
+ config.resources[1].should be_a FileSystem
30
+ config.resources[1].folders.should have(3).items
31
+ config.resources[1].folders.should include 'c:/folder3'
32
+ config.resources[1].folders.should include 'c:/folder4'
33
+ config.resources[1].folders.should include 'c:/folder5'
34
+ end
35
+
36
+ it 'Save postgre sql' do
37
+ config = Configuration.new
38
+
39
+ config.resources.should be_empty
40
+
41
+ config.save PostgreSQL do
42
+ host '192.168.0.0'
43
+ database 'db0'
44
+ username 'user0'
45
+ password 'password0'
46
+ end
47
+
48
+ config.save PostgreSQL do
49
+ host '192.168.0.1'
50
+ database 'db1'
51
+ username 'user1'
52
+ password 'password1'
53
+ end
54
+
55
+ config.resources.should have(2).items
56
+
57
+ (0..1).each do |i|
58
+ config.resources[i].should be_a PostgreSQL
59
+ config.resources[i].host.should eq "192.168.0.#{i}"
60
+ config.resources[i].database.should eq "db#{i}"
61
+ config.resources[i].username.should eq "user#{i}"
62
+ config.resources[i].password.should eq "password#{i}"
63
+ end
64
+
65
+ end
66
+
67
+ it 'In file system' do
68
+ config = Configuration.new
69
+
70
+ config.storages.should be_empty
71
+
72
+ config.into FileSystem do
73
+ folder 'c:/backup'
74
+ end
75
+
76
+ config.into FileSystem do
77
+ folder 'c:/other_backup'
78
+ end
79
+
80
+ config.storages.should have(2).items
81
+ config.storages[0].folders[0].should eq 'c:/backup'
82
+ config.storages[1].folders[0].should eq 'c:/other_backup'
83
+ end
84
+
85
+ it 'Every day at 22:30 and weekly at 03:00' do
86
+ config = Configuration.new
87
+
88
+ config.frequencies.should be_empty
89
+
90
+ config.every 1.day, from: 'today at 22:30'
91
+ config.every 1.week, from: 'today at 03:00'
92
+
93
+ config.frequencies.should have(2).items
94
+ config.frequencies[0].interval.should eq 1.day
95
+ config.frequencies[0].from.should eq Time.local(Time.now.year, Time.now.month, Time.now.day, 22, 30)
96
+ config.frequencies[1].interval.should eq 1.week
97
+ config.frequencies[1].from.should eq Time.local(Time.now.year, Time.now.month, Time.now.day, 3)
98
+ end
99
+
100
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe EasyBackup, '-> Specification' do
4
+
5
+ it 'Simple configuration' do
6
+ backup = EasyBackup.config do
7
+ save PostgreSQL do
8
+ host 'localhost'
9
+ database 'test_db'
10
+ username 'user'
11
+ password 'password'
12
+ end
13
+
14
+ save FileSystem do
15
+ folder 'c:/data'
16
+ end
17
+
18
+ into FileSystem do
19
+ folder 'c:/backup'
20
+ end
21
+
22
+ every 1.day, from: 'today at 22:30'
23
+ end
24
+
25
+ backup[:default].should be_a Configuration
26
+ end
27
+
28
+ it 'Configure from file' do
29
+ backup = EasyBackup.load "#{File.dirname(__FILE__)}/../files/config/backup_config.rb"
30
+
31
+ backup[:test_backup].should be_a Configuration
32
+ end
33
+
34
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe FileSystem, '-> Specification' do
4
+
5
+ it 'Append folders' do
6
+ fs = FileSystem.new
7
+ fs.folder 'c:/folder1'
8
+ fs.folder 'c:/folder2'
9
+
10
+ fs.folders.should have(2).items
11
+ fs.folders.should include('c:/folder1')
12
+ fs.folders.should include('c:/folder2')
13
+ end
14
+
15
+ it 'Append files' do
16
+ fs = FileSystem.new
17
+ fs.file 'c:/file1.txt'
18
+ fs.file 'c:/file2.txt'
19
+
20
+ fs.files.should have(2).items
21
+ fs.files.should include('c:/file1.txt')
22
+ fs.files.should include('c:/file2.txt')
23
+ end
24
+
25
+ it 'Zip files and folders' do
26
+ fs = FileSystem.new
27
+
28
+ fs.zip_file.should be_nil
29
+
30
+ fs.zip 'data.zip'
31
+
32
+ fs.zip_file.should eq 'data.zip'
33
+
34
+ fs.zip lambda { "#{Time.now}.zip" }
35
+
36
+ fs.zip_file.should eq "#{Time.now}.zip"
37
+ end
38
+
39
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe PostgreSQL, '-> Specification' do
4
+
5
+ it 'Specify database parameters' do
6
+ db = PostgreSQL.new
7
+ db.host '192.168.0.1'
8
+ db.port 1234
9
+ db.database 'test_db'
10
+ db.username 'user'
11
+ db.password 'password'
12
+ db.dump_file 'db.sql'
13
+ db.zip
14
+
15
+ db.host.should eq '192.168.0.1'
16
+ db.port.should eq 1234
17
+ db.database.should eq 'test_db'
18
+ db.username.should eq 'user'
19
+ db.password.should eq 'password'
20
+ db.dump_file.should eq 'db.sql'
21
+ db.zip_file.should eq 'db.zip'
22
+ end
23
+
24
+ it 'Get database default parameters' do
25
+ db = PostgreSQL.new
26
+
27
+ db.host.should eq 'localhost'
28
+ db.port.should eq 5432
29
+ db.database.should be_nil
30
+ db.username.should eq 'postgres'
31
+ db.password.should be_nil
32
+ db.dump_file.should eq "#{db.database}_#{Time.now.strftime('%Y%m%d%H%M%S')}.sql"
33
+ db.zip_file.should be_nil
34
+ end
35
+
36
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe SFTP, '-> Specification' do
4
+
5
+ it 'Specify sftp parameters' do
6
+ sftp = SFTP.new
7
+ sftp.host '192.168.0.1'
8
+ sftp.username 'user'
9
+ sftp.password 'password'
10
+ sftp.folder '/backup'
11
+
12
+ sftp.host.should eq '192.168.0.1'
13
+ sftp.username.should eq 'user'
14
+ sftp.password.should eq 'password'
15
+ sftp.folder.should eq '/backup'
16
+ end
17
+
18
+ end
@@ -0,0 +1,7 @@
1
+ module ConfigHelper
2
+ CONFIG_FILE = "#{File.dirname(__FILE__)}/../../config.yaml"
3
+
4
+ def self.get(key)
5
+ YAML.load_file(CONFIG_FILE)[key]
6
+ end
7
+ end
@@ -0,0 +1,25 @@
1
+ module PostgreSQLHelper
2
+
3
+ def self.configuration
4
+ if block_given?
5
+ yield ConfigHelper.get 'postgresql'
6
+ else
7
+ ConfigHelper.get 'postgresql'
8
+ end
9
+ end
10
+
11
+ def self.create_db
12
+ configuration do |c|
13
+ conn = Sequel.connect("postgres://#{c['username']}:#{c['password']}@#{c['host']}:#{c['port']}")
14
+ conn.run "CREATE DATABASE #{c['database']} WITH ENCODING='UTF8' CONNECTION LIMIT=-1;"
15
+ end
16
+ end
17
+
18
+ def self.drop_db
19
+ configuration do |c|
20
+ conn = Sequel.connect("postgres://#{c['username']}:#{c['password']}@#{c['host']}:#{c['port']}")
21
+ conn.run "DROP DATABASE #{c['database']};"
22
+ end
23
+ end
24
+
25
+ end
metadata ADDED
@@ -0,0 +1,175 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: easy_backup
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Gabriel Naiman
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rubyzip
16
+ requirement: &26248488 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *26248488
25
+ - !ruby/object:Gem::Dependency
26
+ name: net-sftp
27
+ requirement: &26248236 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *26248236
36
+ - !ruby/object:Gem::Dependency
37
+ name: active_support
38
+ requirement: &26247984 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *26247984
47
+ - !ruby/object:Gem::Dependency
48
+ name: i18n
49
+ requirement: &26247732 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *26247732
58
+ - !ruby/object:Gem::Dependency
59
+ name: chronic
60
+ requirement: &26247480 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: *26247480
69
+ - !ruby/object:Gem::Dependency
70
+ name: rufus-scheduler
71
+ requirement: &26247228 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: *26247228
80
+ - !ruby/object:Gem::Dependency
81
+ name: sequel
82
+ requirement: &26246976 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *26246976
91
+ - !ruby/object:Gem::Dependency
92
+ name: pg
93
+ requirement: &26246724 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *26246724
102
+ - !ruby/object:Gem::Dependency
103
+ name: rspec
104
+ requirement: &26246472 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: *26246472
113
+ description: Easy DSL to program backups
114
+ email:
115
+ - gabynaiman@gmail.com
116
+ executables: []
117
+ extensions: []
118
+ extra_rdoc_files: []
119
+ files:
120
+ - .gitignore
121
+ - .rspec
122
+ - Gemfile
123
+ - README.md
124
+ - Rakefile
125
+ - easy_backup.gemspec
126
+ - lib/easy_backup.rb
127
+ - lib/easy_backup/adapter/db/postgre_sql.rb
128
+ - lib/easy_backup/adapter/file_system.rb
129
+ - lib/easy_backup/adapter/sftp.rb
130
+ - lib/easy_backup/base.rb
131
+ - lib/easy_backup/configuration.rb
132
+ - lib/easy_backup/extension/net_sftp_session.rb
133
+ - lib/easy_backup/frequency.rb
134
+ - lib/easy_backup/runner.rb
135
+ - lib/easy_backup/version.rb
136
+ - spec/config.yaml
137
+ - spec/execution/runner_spec.rb
138
+ - spec/execution/scheduled_spec.rb
139
+ - spec/files/config/backup_config.rb
140
+ - spec/files/data/sample.json
141
+ - spec/files/data/txt/1/text1.txt
142
+ - spec/files/data/txt/2/text2.txt
143
+ - spec/spec_helper.rb
144
+ - spec/specification/configuration_spec.rb
145
+ - spec/specification/easy_backup_spec.rb
146
+ - spec/specification/file_system_adapter_spec.rb
147
+ - spec/specification/postgre_sql_adapter_spec.rb
148
+ - spec/specification/sftp_adapter_spec.rb
149
+ - spec/support/helpers/config_helper.rb
150
+ - spec/support/helpers/postgre_sql_helper.rb
151
+ homepage: https://github.com/gabynaiman/easy_backup
152
+ licenses: []
153
+ post_install_message:
154
+ rdoc_options: []
155
+ require_paths:
156
+ - lib
157
+ required_ruby_version: !ruby/object:Gem::Requirement
158
+ none: false
159
+ requirements:
160
+ - - ! '>='
161
+ - !ruby/object:Gem::Version
162
+ version: '0'
163
+ required_rubygems_version: !ruby/object:Gem::Requirement
164
+ none: false
165
+ requirements:
166
+ - - ! '>='
167
+ - !ruby/object:Gem::Version
168
+ version: '0'
169
+ requirements: []
170
+ rubyforge_project: easy_backup
171
+ rubygems_version: 1.8.16
172
+ signing_key:
173
+ specification_version: 3
174
+ summary: Easy DSL to program backups
175
+ test_files: []