smarbs 0.9.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.
- data/.autotest +23 -0
- data/History.txt +3 -0
- data/Manifest.txt +28 -0
- data/README.txt +88 -0
- data/Rakefile +10 -0
- data/bin/smarbs +11 -0
- data/lib/backup.rb +275 -0
- data/lib/data/configuration.txt +209 -0
- data/lib/data/iconblue.png +0 -0
- data/lib/data/icongreen.png +0 -0
- data/lib/data/iconred.png +0 -0
- data/lib/data/intro.txt +16 -0
- data/lib/data/outro.txt +15 -0
- data/lib/helpers.rb +438 -0
- data/lib/log.rb +214 -0
- data/lib/script.rb +217 -0
- data/lib/smarbs.rb +5 -0
- data/lib/syslog.rb +98 -0
- data/lib/types.rb +172 -0
- data/test/smarbs_test.rb +114 -0
- data/test/test_backup.rb +171 -0
- data/test/test_helpers.rb +500 -0
- data/test/test_log.rb +128 -0
- data/test/test_script.rb +118 -0
- data/test/test_smarbs.rb +131 -0
- data/test/test_smarbs_test.rb +76 -0
- data/test/test_suite.rb +11 -0
- data/test/test_types.rb +141 -0
- metadata +107 -0
data/.autotest
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'autotest/restart'
|
4
|
+
|
5
|
+
# Autotest.add_hook :initialize do |at|
|
6
|
+
# at.extra_files << "../some/external/dependency.rb"
|
7
|
+
#
|
8
|
+
# at.libs << ":../some/external"
|
9
|
+
#
|
10
|
+
# at.add_exception 'vendor'
|
11
|
+
#
|
12
|
+
# at.add_mapping(/dependency.rb/) do |f, _|
|
13
|
+
# at.files_matching(/test_.*rb$/)
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# %w(TestA TestB).each do |klass|
|
17
|
+
# at.extra_class_map[klass] = "test/test_misc.rb"
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
|
21
|
+
# Autotest.add_hook :run_command do |at|
|
22
|
+
# system "rake build"
|
23
|
+
# end
|
data/History.txt
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
.autotest
|
2
|
+
History.txt
|
3
|
+
Manifest.txt
|
4
|
+
README.txt
|
5
|
+
Rakefile
|
6
|
+
bin/smarbs
|
7
|
+
lib/backup.rb
|
8
|
+
lib/data/configuration.txt
|
9
|
+
lib/data/iconblue.png
|
10
|
+
lib/data/icongreen.png
|
11
|
+
lib/data/iconred.png
|
12
|
+
lib/data/intro.txt
|
13
|
+
lib/data/outro.txt
|
14
|
+
lib/helpers.rb
|
15
|
+
lib/log.rb
|
16
|
+
lib/script.rb
|
17
|
+
lib/smarbs.rb
|
18
|
+
lib/syslog.rb
|
19
|
+
lib/types.rb
|
20
|
+
test/smarbs_test.rb
|
21
|
+
test/test_backup.rb
|
22
|
+
test/test_helpers.rb
|
23
|
+
test/test_log.rb
|
24
|
+
test/test_script.rb
|
25
|
+
test/test_smarbs.rb
|
26
|
+
test/test_smarbs_test.rb
|
27
|
+
test/test_suite.rb
|
28
|
+
test/test_types.rb
|
data/README.txt
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
= smarbs
|
2
|
+
|
3
|
+
* http://smarbs.sourceforge.net
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
smarbs is a backup script written in ruby capable of doing intelligent and
|
8
|
+
automated backups using rsync.
|
9
|
+
|
10
|
+
== FEATURES/PROBLEMS:
|
11
|
+
|
12
|
+
Smarbs was designed to be
|
13
|
+
|
14
|
+
* fast
|
15
|
+
* incremental
|
16
|
+
* able to take full snapshots
|
17
|
+
* space managing
|
18
|
+
* able to handle several sources
|
19
|
+
* automated
|
20
|
+
|
21
|
+
== SYNOPSIS:
|
22
|
+
|
23
|
+
Run smarbs --help to see what options you have. The configfiles are stored
|
24
|
+
in the directory /etc/smarbs or ~/.smarbs, if not executed as root.
|
25
|
+
|
26
|
+
= Syslog
|
27
|
+
|
28
|
+
Smarbs can log to syslog instead of directly to file. Note, you
|
29
|
+
should only enable this feature if you know what you are doing, and
|
30
|
+
have root access.
|
31
|
+
|
32
|
+
Example configuration for syslog-ng, this will log everything "smarbs"
|
33
|
+
into separate file.
|
34
|
+
|
35
|
+
destination smarbs { file("/var/log/smarbs.log"
|
36
|
+
template("$FULLDATE [$LEVEL] $MSG\n")
|
37
|
+
template_escape(no) );
|
38
|
+
};
|
39
|
+
filter f_smarbs { program(smarbs); };
|
40
|
+
log { source(src); filter(f_smarbs); destination(smarbs); };
|
41
|
+
|
42
|
+
To filter out some less important information, try:
|
43
|
+
|
44
|
+
filter f_smarbs { program(smarbs) and level(notice..err); };
|
45
|
+
|
46
|
+
Also, if you put $ISODATE there instead of $FULLDATE, you will get
|
47
|
+
date in ISO-standard format.
|
48
|
+
|
49
|
+
== REQUIREMENTS:
|
50
|
+
|
51
|
+
* Ruby 1.9.1
|
52
|
+
* rsync
|
53
|
+
* standard unix tools (du, df, ...)
|
54
|
+
* optional: ruby-gtk2: For status icon while backupping
|
55
|
+
* optional: syslog-ng: For syslog functionality
|
56
|
+
|
57
|
+
|
58
|
+
== INSTALL:
|
59
|
+
|
60
|
+
* sudo gem install
|
61
|
+
|
62
|
+
== DEVELOPERS:
|
63
|
+
|
64
|
+
After checking out the source, run:
|
65
|
+
|
66
|
+
$ rake newb
|
67
|
+
|
68
|
+
This task will install any missing dependencies, run the tests/specs,
|
69
|
+
and generate the RDoc.
|
70
|
+
|
71
|
+
== LICENSE:
|
72
|
+
|
73
|
+
(GPL)
|
74
|
+
|
75
|
+
Copyright (c) 2009 Jan Rüegg <rggjan@gmail.com>
|
76
|
+
|
77
|
+
Smarbs is free software; you can redistribute it and/or modify it
|
78
|
+
under the terms of the GNU General Public License as published by
|
79
|
+
the Free Software Foundation; either version 3 of the License, or
|
80
|
+
(at your option) any later version.
|
81
|
+
|
82
|
+
This program is distributed in the hope that it will be useful,
|
83
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
84
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
85
|
+
General Public License for more details.
|
86
|
+
|
87
|
+
You can find a copy of the GNU General Public License under
|
88
|
+
http://www.gnu.org/licenses/
|
data/Rakefile
ADDED
data/bin/smarbs
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'script'
|
3
|
+
require 'types'
|
4
|
+
|
5
|
+
$stdout.sync = true # rsync "realtime" output
|
6
|
+
|
7
|
+
if Directory.writable?("/etc/smarbs")
|
8
|
+
script=Script.new("/etc/smarbs", ARGV)
|
9
|
+
else
|
10
|
+
script=Script.new(File.expand_path("~/.smarbs"), ARGV)
|
11
|
+
end
|
data/lib/backup.rb
ADDED
@@ -0,0 +1,275 @@
|
|
1
|
+
require 'log'
|
2
|
+
require 'helpers'
|
3
|
+
require 'types'
|
4
|
+
|
5
|
+
# A class that has individual backups as instances.
|
6
|
+
class Backup
|
7
|
+
|
8
|
+
# Initializes the a backup, takes as arguments a Configfile, some
|
9
|
+
# rsync_arguments and the information if it should be verbose.
|
10
|
+
def initialize(path, rsync_arguments, verbose)
|
11
|
+
@rsync_arguments = rsync_arguments
|
12
|
+
@verbose = verbose
|
13
|
+
@logger = nil
|
14
|
+
@configfile = nil
|
15
|
+
|
16
|
+
begin
|
17
|
+
@configfile = ConfigFile.new(path)
|
18
|
+
|
19
|
+
logfile = @configfile.logfile
|
20
|
+
if logfile == ""
|
21
|
+
if @configfile.logdir == ""
|
22
|
+
logfile = "/tmp/" + Time.now.strftime("%Y-%m-%d.%Hh%M")
|
23
|
+
else
|
24
|
+
logfile = @configfile.logdir + "/" + Time.now.strftime("%Y-%m-%d.%Hh%M")+"-"+@configfile.filename.to_s+".log"
|
25
|
+
end
|
26
|
+
else
|
27
|
+
logfile = @configfile.logfile
|
28
|
+
end
|
29
|
+
|
30
|
+
@logger = Log.new(logfile, @configfile.advancedlog, @configfile.syslog)
|
31
|
+
|
32
|
+
@configfile.write
|
33
|
+
|
34
|
+
@logger.p("-" * 20, 98)
|
35
|
+
@logger.p("Working on " + @configfile.filename, 2)
|
36
|
+
@logger.p("-" * 20, 98)
|
37
|
+
@logger.p("\nChecking configfile...")
|
38
|
+
|
39
|
+
if @configfile.sendmail
|
40
|
+
@logger.initialize_email(@configfile.email, @configfile.smtp,
|
41
|
+
@configfile.port, @configfile.uname, @configfile.passwd,
|
42
|
+
@configfile.tls, @configfile.testm, path.split("/")[-1])
|
43
|
+
if @configfile.testm
|
44
|
+
@logger.p("The test e-mail has been successfully sent to " + @configfile.email + ",", 2, 1)
|
45
|
+
@configfile.testm=false
|
46
|
+
@configfile.write
|
47
|
+
@logger.p("testm has been automatically set to 'no'.", 2, 1)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
raise "No 'rsync' installed!" unless command_exists?("rsync")
|
52
|
+
raise "No 'du' installed!" unless command_exists?("du")
|
53
|
+
raise "No 'df' installed!" unless command_exists?("df")
|
54
|
+
readcf
|
55
|
+
|
56
|
+
if not @configfile.execute_before.empty? then
|
57
|
+
output = `#{@configfile.execute_before} 2>&1`
|
58
|
+
raise "execute_before command '" + @configfile.execute_before + "' was not successful, aborting!\nThis was the output generated:\n" + output unless $?.exitstatus == 0
|
59
|
+
end
|
60
|
+
|
61
|
+
@backup_dir = SmarbsBackupDir.new(@configfile.dest + "/" + "smarbsbackup", @configfile.ignore_leftovers)
|
62
|
+
|
63
|
+
backup
|
64
|
+
|
65
|
+
if not @configfile.execute_after.empty? then
|
66
|
+
output = `#{@configfile.execute_after} 2>&1`
|
67
|
+
raise(AfterException, "execute_after command '" + @configfile.execute_after + "' was not successful, aborting!\nThis was the output generated:\n" + output) unless $?.exitstatus == 0
|
68
|
+
end
|
69
|
+
|
70
|
+
rescue AfterException
|
71
|
+
message = $!.to_s + "\nCheck your configfile " + path + "."
|
72
|
+
if @logger.nil?
|
73
|
+
puts "Error: " + message
|
74
|
+
else
|
75
|
+
@logger.p(message, 4)
|
76
|
+
end
|
77
|
+
rescue NoConfigException
|
78
|
+
@configfile.execute_after = "" if @configfile.execute_after.nil?
|
79
|
+
message = $!.to_s
|
80
|
+
if not @configfile.execute_after.empty? then
|
81
|
+
output = `#{@configfile.execute_after} 2>&1`
|
82
|
+
if $?.exitstatus != 0 then
|
83
|
+
message = "execute_after command '" + @configfile.execute_after + "' was not successful, aborting!\nThis was the output generated:\n" + output + "\nAlso, your backup was aborted: " + message
|
84
|
+
end
|
85
|
+
end
|
86
|
+
if @logger.nil?
|
87
|
+
puts "Error: " + message
|
88
|
+
else
|
89
|
+
@logger.p(message, 4)
|
90
|
+
end
|
91
|
+
rescue
|
92
|
+
message = $!.to_s + "\nCheck your configfile " + path + "."
|
93
|
+
@configfile.execute_after = "" if @configfile.execute_after.nil? unless @configfile.nil?
|
94
|
+
if not @configfile.execute_after.empty? then
|
95
|
+
output = `#{@configfile.execute_after} 2>&1`
|
96
|
+
if $?.exitstatus != 0 then
|
97
|
+
message = "execute_after command '" + @configfile.execute_after + "' was not successful, aborting!\nThis was the output generated:\n" + output + "\nAlso, your backup was aborted: " + message
|
98
|
+
end
|
99
|
+
end unless @configfile.nil?
|
100
|
+
if @logger.nil?
|
101
|
+
puts "Error: " + message
|
102
|
+
else
|
103
|
+
@logger.p(message, 4)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def command_exists?(command)
|
111
|
+
`#{command} --version 2>/dev/null`
|
112
|
+
return $?.exitstatus == 0
|
113
|
+
end
|
114
|
+
|
115
|
+
def readcf
|
116
|
+
raise "No source directory specified!" unless @configfile.src != [""]
|
117
|
+
@configfile.src.each do |dir|
|
118
|
+
raise "Source directory/file " + dir + " not existing!" unless File.directory?(dir) or File.file?(dir)
|
119
|
+
end
|
120
|
+
raise "No destination directory specified!" unless @configfile.dest != ""
|
121
|
+
|
122
|
+
@options = ""
|
123
|
+
@options += " --exclude='" + @configfile.exclude.join("' --exclude='") + "'" unless @configfile.exclude[-1] == ""
|
124
|
+
@options += " -rltD"
|
125
|
+
|
126
|
+
|
127
|
+
@options += "og" if @configfile.preserveowner
|
128
|
+
@options += "p" if @configfile.preservepermissions
|
129
|
+
@options += "v --progress " if @verbose or @configfile.verbose
|
130
|
+
@options += " -x " if @configfile.onefilesystem
|
131
|
+
@options += " --relative " if @configfile.relative
|
132
|
+
@options += " --modify-window=#{@configfile.modifywindow}" if @configfile.modifywindow != 0
|
133
|
+
end
|
134
|
+
|
135
|
+
def make_space(used, avail, text_only=false)
|
136
|
+
@logger.p("", 2)
|
137
|
+
@logger.p("estimated new space used: " + Size.new(used).opt, 2)
|
138
|
+
@logger.p("available space: " + Size.new(avail).opt, 2)
|
139
|
+
@backup_dir.delete(@logger, @configfile.minbackuplevels, @configfile.oldestfirst) unless text_only
|
140
|
+
end
|
141
|
+
|
142
|
+
def delete(to_free)
|
143
|
+
while (@backup_dir.dirlist.size >= @configfile.maxbackuplevels) do
|
144
|
+
@logger.p("", 98)
|
145
|
+
@logger.p("maxbackuplevels: " + @configfile.maxbackuplevels.to_s, 1)
|
146
|
+
@logger.p("backups: " + @backup_dir.dirlist.size.to_s, 1)
|
147
|
+
@backup_dir.delete(@logger, @configfile.minbackuplevels, @configfile.oldestfirst)
|
148
|
+
end unless @configfile.maxbackuplevels == 0
|
149
|
+
|
150
|
+
if @configfile.ownpartition then
|
151
|
+
now_free=@backup_dir.free
|
152
|
+
while to_free > now_free do
|
153
|
+
make_space(to_free, now_free)
|
154
|
+
now_free=@backup_dir.free
|
155
|
+
end
|
156
|
+
make_space(to_free, now_free, true)
|
157
|
+
cursize = @backup_dir.space(true)
|
158
|
+
elsif @configfile.exclusive then
|
159
|
+
cursize=@backup_dir.space
|
160
|
+
while cursize + to_free > @configfile.limit.b do
|
161
|
+
before = @backup_dir.free
|
162
|
+
make_space(to_free, @configfile.limit.b-cursize)
|
163
|
+
after = @backup_dir.free
|
164
|
+
cursize -= (after - before)
|
165
|
+
end
|
166
|
+
make_space(to_free, @configfile.limit.b-cursize, true)
|
167
|
+
else
|
168
|
+
cursize=@backup_dir.space
|
169
|
+
while cursize + to_free > @configfile.limit.b do
|
170
|
+
make_space(to_free, @configfile.limit.b-cursize)
|
171
|
+
cursize=@backup_dir.space
|
172
|
+
end
|
173
|
+
make_space(to_free, @configfile.limit.b-cursize, true)
|
174
|
+
end
|
175
|
+
@logger.p("", 98)
|
176
|
+
return cursize
|
177
|
+
end
|
178
|
+
|
179
|
+
def backup
|
180
|
+
|
181
|
+
dest = @backup_dir.to_s + Time.now.strftime("%Y-%m-%d.%Hh%M") + "-backup.0"
|
182
|
+
|
183
|
+
if @configfile.ignore_leftovers
|
184
|
+
directory_left = @backup_dir.directory_left
|
185
|
+
if directory_left
|
186
|
+
@logger.p("Warning: Aborted backup directory #{directory_left} detected.
|
187
|
+
Resuming backup there because of ignore_leftovers option.", 3)
|
188
|
+
|
189
|
+
orig_dest = dest
|
190
|
+
dest = @backup_dir.to_s + directory_left
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
if @backup_dir.dirlist.size!=0
|
195
|
+
if orig_dest
|
196
|
+
linkdest=@backup_dir.to_s+(@backup_dir.dirlist[1][1]).to_s+"-backup."+(@backup_dir.dirlist[1][0]).to_s
|
197
|
+
else
|
198
|
+
linkdest=@backup_dir.to_s+(@backup_dir.dirlist[0][1]).to_s+"-backup."+(@backup_dir.dirlist[0][0]).to_s
|
199
|
+
end
|
200
|
+
@rsync_arguments += " --link-dest='" + linkdest + "' "
|
201
|
+
end
|
202
|
+
|
203
|
+
@logger.p("\nCalculating required space...", 1)
|
204
|
+
|
205
|
+
required = `rsync #@options #@rsync_arguments -n --stats --delete '#{@configfile.src.join"' '"}' '#{dest}/' 2>/dev/null | tail -n 11 | (read a b c d e f; echo $e)`.to_f
|
206
|
+
|
207
|
+
@logger.p("\nDeleting old backups...", 1)
|
208
|
+
|
209
|
+
begin
|
210
|
+
size_before=delete(required + @configfile.dirspace.b * 1.5)
|
211
|
+
|
212
|
+
@logger.p("Backing up...\n\n", 2)
|
213
|
+
|
214
|
+
system("rsync #@options #@rsync_arguments --delete '#{@configfile.src.join"' '"}' '#{dest}/'")
|
215
|
+
|
216
|
+
success=$?.exitstatus
|
217
|
+
|
218
|
+
case success
|
219
|
+
when 0
|
220
|
+
@logger.p("", 98) if @verbose
|
221
|
+
@logger.p("Successfully backed up.\n\n", 2, 1)
|
222
|
+
@logger.p("Successfully backed up.", 99, 1) if @configfile.successmail
|
223
|
+
when 1
|
224
|
+
raise NoConfigException, "Your --pass-rsync argument '" + @rsync_arguments.to_s + "' is invalid!"
|
225
|
+
when 24
|
226
|
+
@logger.p("Warning: Some files couldn't be transferred because they vanished!", 3)
|
227
|
+
@logger.p("Successfully backed up.\n\n", 2, 1)
|
228
|
+
@logger.p("Successfully backed up.\n\n", 99, 1) if @configfile.successmail
|
229
|
+
when nil
|
230
|
+
raise NoConfigException, "rsync was stopped unexpectedly!"
|
231
|
+
else
|
232
|
+
raise NoConfigException, "rsync failed with error code #{success}."
|
233
|
+
end
|
234
|
+
|
235
|
+
FileUtils.mv dest, orig_dest if orig_dest
|
236
|
+
|
237
|
+
@backup_dir.increment
|
238
|
+
|
239
|
+
size_after = @backup_dir.space(@configfile.ownpartition)
|
240
|
+
newdirspace=size_after - size_before - required
|
241
|
+
newdirspace = newdirspace*1.1 # Safety margin
|
242
|
+
newdirspace = Size.new(newdirspace)
|
243
|
+
if @backup_dir.dirlist.size > 1
|
244
|
+
if newdirspace.b > @configfile.dirspace.b
|
245
|
+
@configfile.dirspace = newdirspace.b
|
246
|
+
@configfile.write
|
247
|
+
else
|
248
|
+
if newdirspace.b >= 0
|
249
|
+
@configfile.dirspace = @configfile.dirspace.b*0.9 + newdirspace.b*0.1
|
250
|
+
else
|
251
|
+
@configfile.dirspace = @configfile.dirspace.b*0.9
|
252
|
+
end
|
253
|
+
@configfile.write
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
size_one = `du -bcs #{@backup_dir.to_s}*backup.1 | tail -1 | (read a b; echo $a)`.strip
|
258
|
+
|
259
|
+
@logger.p("Additional Space used: #{Size.new(size_after - size_before).opt}", 1)
|
260
|
+
@logger.p("Size of all the Backups: #{Size.new(size_after).opt}", 1)
|
261
|
+
@logger.p("Size of one full Backup: #{Size.new(size_one).opt}\n\n", 1)
|
262
|
+
if @configfile.ownpartition then
|
263
|
+
@logger.p("Limit: ignored (ownpartition is set)", 1)
|
264
|
+
else
|
265
|
+
@logger.p("Limit: " + @configfile.limit.opt, 1)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
class AfterException < RuntimeError
|
272
|
+
end
|
273
|
+
|
274
|
+
class NoConfigException < RuntimeError
|
275
|
+
end
|
@@ -0,0 +1,209 @@
|
|
1
|
+
=preferences=
|
2
|
+
|
3
|
+
src: Directory(list)
|
4
|
+
-- One or more directories to the source (= directory or file you need a backup
|
5
|
+
-- backup from. One directory / file per line only.
|
6
|
+
src /directory/to/source1
|
7
|
+
src /directory/to/source2
|
8
|
+
|
9
|
+
dest: Directory
|
10
|
+
-- One (!) destination directory:
|
11
|
+
dest /directory/to/the/destination
|
12
|
+
|
13
|
+
limit: Size
|
14
|
+
-- Limit of space to use for the full and all the incremental backups:
|
15
|
+
-- (ignored when using "ownpartition", see below)
|
16
|
+
limit 20m
|
17
|
+
|
18
|
+
minbackuplevels: Integer(positive)
|
19
|
+
-- Minimum number of backups to keep.
|
20
|
+
-- Smarbs will throw an error if there is not enough space available to backup,
|
21
|
+
-- or the next deletion would go below "minbackuplevels".
|
22
|
+
minbackuplevels 5
|
23
|
+
|
24
|
+
verbose: Boolean
|
25
|
+
-- More output when a yes is here:
|
26
|
+
verbose no
|
27
|
+
|
28
|
+
=filesystems=
|
29
|
+
|
30
|
+
ownpartition: Boolean
|
31
|
+
-- If there is an entire partition just for the backups, then here should be a
|
32
|
+
-- yes. Uses the whole partition for this backup, the limit set above is
|
33
|
+
-- ignored. This is MUCH faster than the normal space calculations, but
|
34
|
+
-- requires an own partition for every backup.
|
35
|
+
ownpartition no
|
36
|
+
|
37
|
+
exclusive: Boolean
|
38
|
+
-- Does deletion using 'df' instead of 'du', what increases speed (much).
|
39
|
+
-- Can ONLY be used, if NO other processes write to the destination partition
|
40
|
+
-- during the backup. Has only an effect when 'ownpartition' is false.
|
41
|
+
exclusive no
|
42
|
+
|
43
|
+
onefilesystem: Boolean
|
44
|
+
-- Don't cross filesystem boundaries. This tells smarbs to avoid crossing a
|
45
|
+
-- filesystem boundary when recursing. This does not limit the user's
|
46
|
+
-- ability to specify items to copy from multiple filesystems.
|
47
|
+
onefilesystem no
|
48
|
+
|
49
|
+
preserveowner: Boolean
|
50
|
+
-- Preserve the owner / group of files:
|
51
|
+
-- Owner preserving does NOT work if the script is not executed as superuser.
|
52
|
+
preserveowner yes
|
53
|
+
|
54
|
+
preservepermissions: Boolean
|
55
|
+
-- Preserve the permissions of files:
|
56
|
+
preservepermissions yes
|
57
|
+
|
58
|
+
modifywindow: Integer
|
59
|
+
-- When comparing two timestamps, smarbs treats the timestamps as being equal
|
60
|
+
-- if they differ by no more than the modifywindow value. This is normally
|
61
|
+
-- 0 (for an exact match), but you may find it useful to set this to a larger
|
62
|
+
-- value in some situations. In particular, when transferring to or from an
|
63
|
+
-- Windows FAT filesystem (which represents times with a 2-second resolution),
|
64
|
+
-- modifywindow 1 is useful (allowing times to differ by up to 1 second).
|
65
|
+
modifywindow 0
|
66
|
+
|
67
|
+
maxbackuplevels: Integer(positive)
|
68
|
+
-- Maximum number of backups to keep.
|
69
|
+
-- Smarbs will delete backups if there are more incremental backups than given
|
70
|
+
-- here. This may be useful if space calculations take too much time (due to
|
71
|
+
-- more and more incremental backups and hardlinks).
|
72
|
+
-- 0 means infinity and is recommended, if the speed is acceptable.
|
73
|
+
maxbackuplevels 0
|
74
|
+
|
75
|
+
dirspace: Size
|
76
|
+
-- How much space is used by hardlinks and directories? Used to do space
|
77
|
+
-- calculations. Should be adapted automatically by smarbs, so you shouldn't
|
78
|
+
-- have to touch that...
|
79
|
+
dirspace 1m
|
80
|
+
|
81
|
+
=advanced=
|
82
|
+
|
83
|
+
execute_before: String
|
84
|
+
-- A command to execute (in a shell) before the backup is done.
|
85
|
+
-- Example:
|
86
|
+
-- execute_before mount /directory/to/source1
|
87
|
+
execute_before
|
88
|
+
|
89
|
+
execute_after: String
|
90
|
+
-- A command to execute (in a shell) after the backup , regardless if it was
|
91
|
+
-- successful or not.
|
92
|
+
-- Example:
|
93
|
+
-- execute_after umount /directory/to/source1
|
94
|
+
execute_after
|
95
|
+
|
96
|
+
relative: Boolean
|
97
|
+
-- Use relative paths. This means that the full path names of the sources are
|
98
|
+
-- sent to the backup folder rather than just the last parts of the filenames.
|
99
|
+
-- This is particularly useful when you want to backup several different
|
100
|
+
-- directories with the same name, or to preserve a whole directory structure.
|
101
|
+
-- So you get .../smarbsbackup/2008-03-01.11h10-backup.1/directory/to/source1
|
102
|
+
-- instead of just .../smarbsbackup/2008-03-01.11h10-backup.1/source1
|
103
|
+
relative no
|
104
|
+
|
105
|
+
oldestfirst: Boolean
|
106
|
+
-- Delete the oldest backups first when no more space is available, instead of
|
107
|
+
-- using the established "powers of two" algorithm, that keeps the backups 1,
|
108
|
+
-- 2, 4, 8, 16, 32 etc. Recommended to set to 'no'!
|
109
|
+
-- See https://sourceforge.net/apps/trac/smarbs/wiki/DeletionAlgorithm for more
|
110
|
+
-- informations.
|
111
|
+
oldestfirst no
|
112
|
+
|
113
|
+
exclude: String(list)
|
114
|
+
-- Directories / files to exclude. Path relative to the "root of transfer" when
|
115
|
+
-- starting with a "/". So "exclude /source1/foo" excludes files or directories
|
116
|
+
-- named foo in /directory/to/source1 while "exclude foo" excludes EVERY
|
117
|
+
-- directory or file named foo in source1 or source2. "exclude sub/foo" would
|
118
|
+
-- exclude EVERY file or directory named foo which is in a folder "sub".
|
119
|
+
-- Syntax: One line per exclude.
|
120
|
+
-- Example:
|
121
|
+
-- exclude *.jpg
|
122
|
+
-- exclude /sub/*/foo
|
123
|
+
exclude
|
124
|
+
|
125
|
+
ignore_leftovers: Boolean
|
126
|
+
-- Normally, when an aborted backup directory (...backup.0 instead of 1) is
|
127
|
+
-- detected, smarbs treats this as an error, stops and does not do a backup at
|
128
|
+
-- at all. When ignore_leftovers is set to "yes", it just prints a warning and
|
129
|
+
-- continues the last backup.
|
130
|
+
ignore_leftovers: no
|
131
|
+
|
132
|
+
=logging=
|
133
|
+
|
134
|
+
logfile: Directory
|
135
|
+
-- Place of the (error) log file:
|
136
|
+
-- Example:
|
137
|
+
-- logfile /home/me/smarbslog.log
|
138
|
+
logfile
|
139
|
+
|
140
|
+
logdir: Directory
|
141
|
+
-- Place of a possible log directory. Has no effect when a logfile is set.
|
142
|
+
-- Otherwise, instead of writing logs into one file, logfiles are stored in the
|
143
|
+
-- directory below like this for each backup:
|
144
|
+
-- /.../logdir/2009-02-06.20h09-backup1.log
|
145
|
+
-- If logfile and logdir are not set, the logdir will be /tmp/
|
146
|
+
-- Example:
|
147
|
+
-- logdir /home/me/smarbslogs/
|
148
|
+
logdir
|
149
|
+
|
150
|
+
advancedlog: Boolean
|
151
|
+
-- Do advanced logging (show deletions, space informations etc. instead of just
|
152
|
+
-- success and failure messages).
|
153
|
+
advancedlog yes
|
154
|
+
|
155
|
+
syslog: Boolean
|
156
|
+
-- Log to syslog instead of build-in logger, above options will be ignored.
|
157
|
+
-- You will have to configure your syslog daemon accordingly, check README for
|
158
|
+
-- examples.
|
159
|
+
-- DO NOT enable unless you know what you are doing, and have root access
|
160
|
+
syslog no
|
161
|
+
|
162
|
+
=email notification=
|
163
|
+
|
164
|
+
sendmail: Boolean
|
165
|
+
-- Send an email in case of an error, the logfile will be attached.
|
166
|
+
sendmail no
|
167
|
+
|
168
|
+
successmail: Boolean
|
169
|
+
-- Send also an email for successful backups:
|
170
|
+
successmail no
|
171
|
+
|
172
|
+
email: String
|
173
|
+
-- Email address to send it to.
|
174
|
+
-- Example:
|
175
|
+
-- email rggjan@gmail.com
|
176
|
+
email
|
177
|
+
|
178
|
+
smtp: String
|
179
|
+
-- Smtp server.
|
180
|
+
-- Example:
|
181
|
+
-- smtp smtp-auth.freesurf.ch
|
182
|
+
smtp
|
183
|
+
|
184
|
+
port: Integer
|
185
|
+
-- Port to use:
|
186
|
+
port 25
|
187
|
+
|
188
|
+
uname: String
|
189
|
+
-- When authentication is required, put here the username.
|
190
|
+
-- Example:
|
191
|
+
-- uname rggjan@gmail.com
|
192
|
+
uname
|
193
|
+
|
194
|
+
passwd: String
|
195
|
+
-- When authentication is required, put here the username.
|
196
|
+
-- Example:
|
197
|
+
-- passwd topsecret
|
198
|
+
passwd
|
199
|
+
|
200
|
+
tls: Boolean
|
201
|
+
-- Use tls (ssl). That's required for some smtp servers like Gmail.
|
202
|
+
-- You need to have ruby-openssl installed to use this!
|
203
|
+
tls no
|
204
|
+
|
205
|
+
testm: Boolean
|
206
|
+
-- Send a test email to see if your smtp options are ok. This should
|
207
|
+
-- definitely be a "yes" at the beginning to check if the connection works.
|
208
|
+
-- Will be automatically set to "no" once the email is successfully sent.
|
209
|
+
testm yes
|
Binary file
|
Binary file
|
Binary file
|
data/lib/data/intro.txt
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
Smarbs space-managing-rsync-backup-script
|
2
|
+
rsync and ruby are required!
|
3
|
+
|
4
|
+
For each different backup you should create a file like this in the directory
|
5
|
+
/home/"user"/.smarbs/ (or /etc/smarbs/ if you are root).
|
6
|
+
|
7
|
+
You can start a backup using "smarbs backup1" or "smarbs homebackup" assuming
|
8
|
+
there is a file named "backup1" or "homebackup" in the smarbs folder.
|
9
|
+
A simple "smarbs" or a "smarbs all" will do a backup with all the different
|
10
|
+
configurations in the smarbs directory.
|
11
|
+
|
12
|
+
Sizes: 2394 Bytes (B) => 2394
|
13
|
+
32 Kibibytes (MiB) => 32k
|
14
|
+
54 Mebibytes (MiB) => 54m
|
15
|
+
2 Gibibytes (KiB) => 2g
|
16
|
+
|
data/lib/data/outro.txt
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
-------------------------------end of preferences-------------------------------
|
2
|
+
|
3
|
+
This program is free software: you can redistribute it and/or modify
|
4
|
+
it under the terms of the GNU General Public License as published by
|
5
|
+
the Free Software Foundation, either version 3 of the License, or
|
6
|
+
(at your option) any later version.
|
7
|
+
|
8
|
+
This program is distributed in the hope that it will be useful,
|
9
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
GNU General Public License for more details.
|
12
|
+
|
13
|
+
See <http://www.gnu.org/licenses/> for a copy of the GNU General Public License.
|
14
|
+
|
15
|
+
For any suggestions, comments or bug reports, write to rggjan@gmail.com
|