outback 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +6 -1
- data/README.md +134 -0
- data/VERSION +1 -1
- data/lib/outback/backup.rb +1 -0
- data/lib/outback/directory_source.rb +1 -1
- data/lib/outback/directory_target.rb +6 -1
- data/lib/outback/mysql_source.rb +1 -1
- data/lib/outback/s3_archive.rb +11 -2
- data/lib/outback/s3_target.rb +23 -14
- data/lib/outback/target.rb +9 -1
- data/lib/outback.rb +2 -1
- metadata +6 -5
data/CHANGELOG
CHANGED
data/README.md
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
Welcome to Outback
|
2
|
+
==================
|
3
|
+
|
4
|
+
Outback is a Ruby backup tool, enabling you to create backups of
|
5
|
+
your server files and databases and storing them in a local or
|
6
|
+
remote repository. Using a simple DSL, you can specify multiple
|
7
|
+
sources that generate backup data, as well as multiple targets,
|
8
|
+
where backups are going to be stored.
|
9
|
+
|
10
|
+
Outback configuration files are pure Ruby, so writing dynamic
|
11
|
+
configurations or even customized backup sources and targets is a
|
12
|
+
piece of cake.
|
13
|
+
|
14
|
+
Installation
|
15
|
+
------------
|
16
|
+
$ gem install outback
|
17
|
+
|
18
|
+
Then you can invoke outback from the command line:
|
19
|
+
|
20
|
+
$ outback --help
|
21
|
+
|
22
|
+
A simple configuration example
|
23
|
+
------------------------------
|
24
|
+
|
25
|
+
You can instantiate as many configurations as you like.
|
26
|
+
Outback will enqueue and execute all configurations that were
|
27
|
+
instantiated during a single run.
|
28
|
+
|
29
|
+
```` ruby
|
30
|
+
Outback::Configuration.new 'name' do
|
31
|
+
source :directory, '/ver/www' do
|
32
|
+
exclude '/var/www/foo'
|
33
|
+
exclude '/var/www/icons/*.png'
|
34
|
+
end
|
35
|
+
|
36
|
+
source :mysql do
|
37
|
+
user 'mysqlusername'
|
38
|
+
password 'mysqlpassword'
|
39
|
+
host 'localhost'
|
40
|
+
exclude 'mysql', 'information_schema'
|
41
|
+
|
42
|
+
#
|
43
|
+
# If you do not specify a specific database, all databases
|
44
|
+
# will be dumped and included in the backup
|
45
|
+
# database 'specific_database'
|
46
|
+
end
|
47
|
+
|
48
|
+
# Amazon S3 storage
|
49
|
+
target :s3 do
|
50
|
+
access_key 'S3 access key'
|
51
|
+
secret_key 'S3 secret key'
|
52
|
+
bucket_name 'bucketname'
|
53
|
+
prefix 'backups/daily'
|
54
|
+
|
55
|
+
# Backups will be purged after the time specified here.
|
56
|
+
# Just omit the definition to keep archives forever.
|
57
|
+
ttl 1.month
|
58
|
+
end
|
59
|
+
|
60
|
+
# Store on a local filesystem path
|
61
|
+
target :directory, '/media/backups/daily' do
|
62
|
+
# If you specify the move option, archives will be moved from the temporary
|
63
|
+
# filesystem location in order to speed up things. Otherwise, archives will
|
64
|
+
# be copied. Note that a 'move'-to target must be specified last in the target
|
65
|
+
# chain.
|
66
|
+
move true
|
67
|
+
ttl 1.day
|
68
|
+
user 'root'
|
69
|
+
group 'root'
|
70
|
+
directory_permissions 0700
|
71
|
+
archive_permissions 0600
|
72
|
+
end
|
73
|
+
end
|
74
|
+
````
|
75
|
+
|
76
|
+
Default configurations and commandline options
|
77
|
+
----------------------------------------------
|
78
|
+
|
79
|
+
If you place your backup configurations in the file `/etc/outback.conf` they
|
80
|
+
will be read automatically when the outback executable is invoked. Make
|
81
|
+
sure to have correct permissions on the configuration files, as they might
|
82
|
+
include database passwords.
|
83
|
+
|
84
|
+
Alternatively, you can pass in the configuration file to read as a
|
85
|
+
commandline argument. The default configuration file in /etc will then be
|
86
|
+
ignored:
|
87
|
+
|
88
|
+
$ outback ./my_config.rb
|
89
|
+
|
90
|
+
If you have several backup configurations in a single file, say, for daily
|
91
|
+
and monthly backups, you can use the `-c` commandline option to select the
|
92
|
+
backup to be invoked:
|
93
|
+
|
94
|
+
$ outback -c 'myservername-daily'
|
95
|
+
|
96
|
+
This will run only the backup with the specified name, which enables you to
|
97
|
+
write DRY configurations like this:
|
98
|
+
|
99
|
+
```` ruby
|
100
|
+
{ :daily => [14.days, 5.days], :monthly => [1.year, 1.year] }.each do |frequency, ttls|
|
101
|
+
s3_ttl, directory_ttl = ttls
|
102
|
+
|
103
|
+
Outback::Configuration.new "yourserver-#{frequency}" do
|
104
|
+
source :directory, '/home'
|
105
|
+
source :directory, '/var/svn'
|
106
|
+
|
107
|
+
target :s3 do
|
108
|
+
access_key 'foo'
|
109
|
+
secret_key 'foo'
|
110
|
+
bucket_name 'somebucket'
|
111
|
+
prefix "yourserver/#{frequency}"
|
112
|
+
ttl s3_ttl
|
113
|
+
end
|
114
|
+
|
115
|
+
target :directory, "/media/backups/#{frequency}" do
|
116
|
+
move true
|
117
|
+
ttl directory_ttl
|
118
|
+
user 'root'
|
119
|
+
group 'root'
|
120
|
+
directory_permissions 0700
|
121
|
+
archive_permissions 0600
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
````
|
126
|
+
|
127
|
+
Other commandline options are:
|
128
|
+
|
129
|
+
* `-v` `--verbose` be talky
|
130
|
+
* `-s` `--silent` be silent
|
131
|
+
* `-t` `--test` test configuration, then exit
|
132
|
+
* `-l` `--list` list available configurations, then exit
|
133
|
+
* `-h` `--help` display help
|
134
|
+
* `--version` display version
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.8
|
data/lib/outback/backup.rb
CHANGED
@@ -27,7 +27,7 @@ module Outback
|
|
27
27
|
Outback.debug "executing command: #{commandline}"
|
28
28
|
result = `#{commandline}`
|
29
29
|
Outback.debug "result: #{result}"
|
30
|
-
Outback.info "
|
30
|
+
Outback.info "Archived directory #{path}"
|
31
31
|
[TempArchive.new(archive_name, self)]
|
32
32
|
end
|
33
33
|
end
|
@@ -11,6 +11,10 @@ module Outback
|
|
11
11
|
(user and group) or (not user and not group)
|
12
12
|
end
|
13
13
|
|
14
|
+
def display_name
|
15
|
+
"directory:#{path}"
|
16
|
+
end
|
17
|
+
|
14
18
|
def put(archives)
|
15
19
|
Dir.mkdir(path) unless path.directory?
|
16
20
|
FileUtils.chmod directory_permissions || 0700, path
|
@@ -33,7 +37,8 @@ module Outback
|
|
33
37
|
end
|
34
38
|
size += archived_file.size
|
35
39
|
end
|
36
|
-
Outback.info "#{move ? 'Moved' : 'Copied'} #{archives.size} archives (#{size} bytes) to
|
40
|
+
Outback.info "#{move ? 'Moved' : 'Copied'} #{archives.size} archives (#{size} bytes) to #{display_name}"
|
41
|
+
archives.size
|
37
42
|
end
|
38
43
|
|
39
44
|
def list_archives(name)
|
data/lib/outback/mysql_source.rb
CHANGED
@@ -41,7 +41,7 @@ module Outback
|
|
41
41
|
commandline = "mysqldump --defaults-extra-file=#{mysql_conf_file} --opt --user=#{user} --host=#{mysql_host} --port=#{mysql_port} #{database} | gzip > #{archive_name}"
|
42
42
|
result = `#{commandline}`.strip
|
43
43
|
Outback.debug(result) unless result.blank?
|
44
|
-
Outback.info "
|
44
|
+
Outback.info "Archived database #{database}"
|
45
45
|
TempArchive.new(archive_name, self).tap { |archive| Outback.debug "dumped #{archive.filename.basename} with #{archive.size} bytes" }
|
46
46
|
end
|
47
47
|
end
|
data/lib/outback/s3_archive.rb
CHANGED
@@ -1,9 +1,18 @@
|
|
1
1
|
module Outback
|
2
2
|
class S3Archive < Archive
|
3
|
+
def size
|
4
|
+
object.size.to_i
|
5
|
+
end
|
6
|
+
|
3
7
|
def purge!
|
4
8
|
Outback.debug "purging S3Archive: #{filename}"
|
5
|
-
|
6
|
-
|
9
|
+
object && object.destroy or Outback.error("could not find object #{filename} for purging")
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def object
|
15
|
+
parent.bucket.objects.find(filename.to_s)
|
7
16
|
end
|
8
17
|
end
|
9
18
|
end
|
data/lib/outback/s3_target.rb
CHANGED
@@ -1,37 +1,46 @@
|
|
1
1
|
module Outback
|
2
2
|
class S3Target < Target
|
3
|
-
attr_setter :
|
3
|
+
attr_setter :bucket_name, :access_key, :secret_key, :ttl, :prefix
|
4
|
+
|
5
|
+
def display_name
|
6
|
+
"s3:#{bucket_name}/#{prefix}"
|
7
|
+
end
|
4
8
|
|
5
9
|
def valid?
|
6
|
-
|
10
|
+
bucket_name && access_key && secret_key
|
11
|
+
end
|
12
|
+
|
13
|
+
def service(force_reconnect = false)
|
14
|
+
@service = nil if force_reconnect
|
15
|
+
@service ||= S3::Service.new(:access_key_id => access_key, :secret_access_key => secret_key)
|
7
16
|
end
|
8
17
|
|
9
|
-
def
|
10
|
-
|
11
|
-
@connection ||= AWS::S3::Base.establish_connection!(:access_key_id => access_key, :secret_access_key => secret_key)
|
18
|
+
def bucket
|
19
|
+
service.buckets.find(bucket_name)
|
12
20
|
end
|
13
21
|
|
14
22
|
def put(archives)
|
15
|
-
|
16
|
-
size, count = 0, 0
|
23
|
+
size = count = 0
|
17
24
|
archives.each do |archive|
|
18
25
|
object_name = [prefix.to_s, archive.filename.basename.to_s].join('/')
|
19
|
-
Outback.debug "S3Target: storing #{archive.filename} in s3://#{
|
20
|
-
|
21
|
-
|
26
|
+
Outback.debug "S3Target: storing #{archive.filename} in s3://#{bucket_name}/#{object_name}"
|
27
|
+
object = bucket.objects.build(object_name)
|
28
|
+
object.content = archive.open
|
29
|
+
object.acl = :private
|
30
|
+
object.save
|
31
|
+
if object.exists?
|
22
32
|
size += archive.size
|
23
33
|
count += 1
|
24
34
|
else
|
25
35
|
Outback.error "S3 archive upload failed: #{object_name}"
|
26
36
|
end
|
27
37
|
end
|
28
|
-
Outback.
|
29
|
-
|
38
|
+
Outback.info "Uploaded #{count} archives (#{size} bytes) to #{display_name}"
|
39
|
+
count
|
30
40
|
end
|
31
41
|
|
32
42
|
def list_archives(name)
|
33
|
-
|
34
|
-
entries = AWS::S3::Bucket.objects(bucket).select { |e| e.key.start_with?(prefix.to_s) && e.key[prefix.to_s.size..-1].match(Archive::NAME_PATTERN) }
|
43
|
+
entries = bucket.objects.select { |e| e.key.start_with?(prefix.to_s) && e.key[prefix.to_s.size..-1].match(Archive::NAME_PATTERN) }
|
35
44
|
entries.map { |e| S3Archive.new(e.key, self) }.select(&its.backup_name == name)
|
36
45
|
end
|
37
46
|
end
|
data/lib/outback/target.rb
CHANGED
@@ -7,7 +7,15 @@ module Outback
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def purge!(name)
|
10
|
-
|
10
|
+
size = count = 0
|
11
|
+
outdated_archives(name).each do |archive|
|
12
|
+
archive_size = archive.size
|
13
|
+
if archive.purge!
|
14
|
+
count += 1
|
15
|
+
size += archive_size
|
16
|
+
end
|
17
|
+
end
|
18
|
+
Outback.info "Purged #{count} archives (#{size} bytes) from #{display_name}"
|
11
19
|
end
|
12
20
|
|
13
21
|
end
|
data/lib/outback.rb
CHANGED
@@ -5,7 +5,7 @@ require 'tmpdir'
|
|
5
5
|
|
6
6
|
require 'active_support/core_ext'
|
7
7
|
|
8
|
-
require '
|
8
|
+
require 's3'
|
9
9
|
|
10
10
|
require 'outback/vendor/mysql'
|
11
11
|
require 'outback/vendor/metaclass'
|
@@ -55,6 +55,7 @@ module Outback
|
|
55
55
|
def error(message, options = nil)
|
56
56
|
return if silent?
|
57
57
|
puts "Outback error: #{message}"
|
58
|
+
false
|
58
59
|
end
|
59
60
|
end
|
60
61
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: outback
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 8
|
10
|
+
version: 0.0.8
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Matthias Grosser
|
@@ -16,11 +16,11 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2012-03-
|
19
|
+
date: 2012-03-21 00:00:00 +01:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
23
|
-
name:
|
23
|
+
name: s3
|
24
24
|
prerelease: false
|
25
25
|
requirement: &id001 !ruby/object:Gem::Requirement
|
26
26
|
none: false
|
@@ -85,6 +85,7 @@ files:
|
|
85
85
|
- bin/outback
|
86
86
|
- MIT-LICENSE
|
87
87
|
- VERSION
|
88
|
+
- README.md
|
88
89
|
- CHANGELOG
|
89
90
|
has_rdoc: true
|
90
91
|
homepage: http://rubygems.org/gems/outback
|