easy_backup 0.0.1

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.
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: []