summaryrefslogtreecommitdiff
path: root/byteback-snapshot
diff options
context:
space:
mode:
authorMatthew Bloch <matthew@bytemark.co.uk>2014-01-08 12:36:04 +0000
committerMatthew Bloch <matthew@bytemark.co.uk>2014-01-08 12:36:04 +0000
commit90f28caf1017fab772fafa00e494bd5ed2f22cc3 (patch)
treee7fbee9f4fd215628904d72ac3532effdcc13e68 /byteback-snapshot
parent760e0243daa0db0baef0ec209cd3fe5639c82fcb (diff)
Trying new calculation for amount of space needed for prune, forbid snapshot at more than 6 hour intervals.
Diffstat (limited to 'byteback-snapshot')
-rw-r--r--byteback-snapshot38
1 files changed, 28 insertions, 10 deletions
diff --git a/byteback-snapshot b/byteback-snapshot
index dfd216f..daf368b 100644
--- a/byteback-snapshot
+++ b/byteback-snapshot
@@ -115,14 +115,18 @@ class BackupDirectory
snapshot_times_sorted
end
- # Returns the size of the last completed snapshot (runs du, maybe slow)
+ # Returns the size of the given snapshot (runs du, may be slow)
#
# Would much prefer to take advantage of this feature:
# http://dustymabe.com/2013/09/22/btrfs-how-big-are-my-snapshots/
# but it's not currently in Debian/wheezy.
#
- def latest_snapshot_size
- `du -s -b #{snapshot_path(snapshot_times.last)}`.to_i
+ def snapshot_size(time=snapshot_times.latest)
+ `du -s -b #{snapshot_path(time)}`.to_i
+ end
+
+ def average_snapshot_size(number=10)
+ snapshot_times.sort[0..number].inject(0) { |time, total| snapshot_size(time) } / number
end
# Create a new snapshot of 'current'
@@ -159,6 +163,7 @@ opts = Trollop::options do
opt :snapshot, "Take a new snapshot"
opt :prune, "Prune old backups"
+ :type => :string
opt :list, "List backups (by 'age' or 'importance')",
:type => :string
@@ -179,16 +184,28 @@ error("--root not readable") unless File.directory?(@root)
@backups = BackupDirectory.new(@root)
+def get_snapshots_by(method)
+ if method == 'importance'
+ @backups.snapshot_times_by_importance.reverse # least important first
+ elsif method == 'age'
+ @backups.snapshot_times
+ else
+ raise ArgumentError.new("Unknown snapshot sort method #{method}")
+ end
+end
if @do_snapshot
+ last_snapshot_time = @backups.snapshots.last
+ error("Last snapshot was less than six hours ago") unless
+ !last_snapshot_time ||
+ Time.now - @backups.snapshots.last >= 6*60*60 # FIXME: make configurable
+
verbose "Making new snapshot"
@backups.new_snapshot!
end
if @do_list
- list = @do_list == 'age' ?
- @backups.snapshot_times : # oldest first
- @backups.snapshot_times_by_importance.reverse # least important first
+ list = get_snapshots_by(@do_list)
print "Backups in #{@root} by #{@do_list}:\n"
list.each_with_index do |time, index|
print "#{sprintf('% 3d',index)}: #{time}\n"
@@ -196,16 +213,17 @@ if @do_list
end
if @do_prune
- target_free_space = @backups.latest_snapshot_size
+ verbose "Counting last 10 backups"
+ target_free_space = 1.5 * @backups.average_snapshot_size(10)
verbose "Want to ensure we have #{target_free_space}"
if @backups.free >= target_free_space
verbose "(we have #{@backups.free} so no action needed)"
else
- snapshot_times_by_importance = @backups.snapshot_times_by_importance
+ list = get_snapshots_by(@do_prune)
- while @backups.free < target_free_space && !snapshot_times_by_importance.empty?
- to_delete = snapshot_times_by_importance.pop
+ while @backups.free < target_free_space && !list.empty?
+ to_delete = list.pop
verbose "Deleting #{to_delete}"
@backups.delete_snapshot!(to_delete)
verbose "Leaves us with #{@backups.free}"