Merge lp:~mterry/deja-dup/simple-threshold into lp:deja-dup/24

Proposed by Michael Terry
Status: Merged
Merged at revision: 1354
Proposed branch: lp:~mterry/deja-dup/simple-threshold
Merge into: lp:deja-dup/24
Diff against target: 281 lines (+46/-134)
9 files modified
common/CommonUtils.vala (+9/-29)
data/org.gnome.DejaDup.gschema.xml.in (+5/-0)
tests/Makefile.am (+0/-1)
tests/backup/full (+0/-89)
tests/scripts/threshold-full.test (+15/-0)
tests/scripts/threshold-inc.test (+16/-0)
widgets/ConfigDelete.vala (+0/-6)
widgets/ConfigLabelPolicy.vala (+1/-7)
widgets/ConfigPeriod.vala (+0/-2)
To merge this branch: bzr merge lp:~mterry/deja-dup/simple-threshold
Reviewer Review Type Date Requested Status
Ken VanDine Approve
Review via email: mp+111431@code.launchpad.net

Description of the change

Some backstory:

Deja Dup needs to make the occasional fresh, full backup. Further, it makes sure to always keep two of these around.

It does this so that it can delete old complete chains (if your backup was just one full backup a year ago and incrementals since, it couldn't delete any of it). And so that if something went wrong with one of your backups, you'll always have a second. Plus, upstream duplicity recommends the practice.

However, users have been complaining that Deja Dup makes a full backup too frequently (typically when they change the schedule to daily, which triggers monthly full backups). And some administrators have requested the ability to tune this value for their users.

This branch does a few things:

1) Allow a user/administrator to set (only via gsettings) the "how many days since the last full backup?" threshold for a new full backup.
2) Set that new setting to 90 (three months, which is the same default for weekly backups as before, but for users with daily backups, this represents a change from one month).
3) Removes UI options to backup at "two weeks" and "monthly" intervals (keeping "daily" and the default "weekly"). The user can still set a custom value in gsettings.
4) Removes UI options to only hold backups for "one month", "two months", and "three months" (keeping "six months", "one year", and the default "forever"). The user can still set a custom value in gsettings.
5) Vastly simplifies the existing 'threshold' logic to just look up in gsettings what the value should be. Previously it calculated it based on the user's delete date (divide by 2) and backup interval (multiply by 12) with clamps of (1 month, 6 months).

The reason for 3 is because I've been trying to encourage shorter backup intervals. This seemed like a good time to drop those options, while I was futzing with these things.

The reason for 4 is because if we're always keeping two full backups, spaced three months apart, the soonest we will delete anything is six months.

And while I was at it, I converted the relevant old-style test to a new-style one.

To post a comment you must log in.
lp:~mterry/deja-dup/simple-threshold updated
1354. By Michael Terry

whoops, forgot to update the new test thresholds to match 90 instead of 84

Revision history for this message
Ken VanDine (ken-vandine) wrote :

I'm having trouble figuring out how to run the new style tests, in the tests/scripts directory. It looks like I should run "make check" in the tests/runner directory, but they all fail. Tips?

Revision history for this message
Michael Terry (mterry) wrote :

Yeah, make check should work. Maybe they assume something that only happens to be true for my dev machine. Let's chat on IRC about it.

Revision history for this message
Ken VanDine (ken-vandine) wrote :

My test failures were due to ~/Downloads being a symlink on my box, tests pass on another box.

Looks good!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'common/CommonUtils.vala'
2--- common/CommonUtils.vala 2012-04-30 06:19:13 +0000
3+++ common/CommonUtils.vala 2012-06-21 17:50:33 +0000
4@@ -33,6 +33,7 @@
5 public const string PERIODIC_KEY = "periodic";
6 public const string PERIODIC_PERIOD_KEY = "periodic-period";
7 public const string DELETE_AFTER_KEY = "delete-after";
8+public const string FULL_BACKUP_PERIOD_KEY = "full-backup-period";
9
10 public errordomain BackupError {
11 BAD_CONFIG,
12@@ -501,43 +502,22 @@
13
14 public int get_full_backup_threshold()
15 {
16- int threshold = 7 * 6; // default to 6 weeks
17 // So, there are a few factors affecting how often to make a fresh full
18 // backup:
19+ //
20 // 1) The longer we wait, the more we're filling up the backend with
21 // iterations on the same crap.
22 // 2) The longer we wait, there's a higher risk that some bit will flip
23- // and the whole backup is toast.
24+ // and the whole incremental chain afterwards is toast.
25 // 3) The longer we wait, the less annoying we are, since full backups
26 // take a long time.
27- // So we try to do them at reasonable times. But almost nobody should be
28- // going longer than 6 months without a full backup. Further, we want
29- // to try to keep at least 2 full backups around, so also don't allow a
30- // longer full threshold than half the delete age.
31- //
32- // 'daily' gets 2 weeks: 1 * 12 => 2 * 7
33- // 'weekly' gets 3 months: 7 * 12
34- // 'biweekly' gets 6 months: 14 * 12
35- // 'monthly' gets 6 months: 28 * 12 => 24 * 7
36- var max = 24 * 7; // 6 months
37- var min = 4 * 7; // 4 weeks
38- var scale = 12;
39- var min_fulls = 2;
40-
41+ //
42+ // We default to 3 months.
43+
44 var settings = get_settings();
45- var delete_age = settings.get_int(DELETE_AFTER_KEY);
46- if (delete_age > 0)
47- max = int.max(int.min(delete_age/min_fulls, max), min);
48-
49- var periodic = settings.get_boolean(PERIODIC_KEY);
50- if (periodic) {
51- var period = settings.get_int(PERIODIC_PERIOD_KEY);
52- threshold = period * scale;
53- threshold.clamp(min, max);
54- }
55- else
56- threshold = max;
57-
58+ var threshold = settings.get_int(FULL_BACKUP_PERIOD_KEY);
59+ if (threshold < 1)
60+ threshold = 84; // 3 months
61 return threshold;
62 }
63
64
65=== modified file 'data/org.gnome.DejaDup.gschema.xml.in'
66--- data/org.gnome.DejaDup.gschema.xml.in 2011-08-31 03:50:06 +0000
67+++ data/org.gnome.DejaDup.gschema.xml.in 2012-06-21 17:50:33 +0000
68@@ -55,6 +55,11 @@
69 <_summary>How long to keep backup files</_summary>
70 <_description>The number of days to keep backup files on the backup location. A value of 0 means forever. This is a minimum number of days; the files may be kept longer.</_description>
71 </key>
72+ <key name="full-backup-period" type="i">
73+ <default>90</default>
74+ <_summary>How long to wait between full backups</_summary>
75+ <_description>Déjà Dup needs to occasionally make fresh full backups. This is the number of days to wait between full backups.</_description>
76+ </key>
77 <key name="backend" type="s">
78 <choices>
79 <choice value='auto'/>
80
81=== modified file 'tests/Makefile.am'
82--- tests/Makefile.am 2012-04-18 14:02:29 +0000
83+++ tests/Makefile.am 2012-06-21 17:50:33 +0000
84@@ -29,7 +29,6 @@
85 backup/delete \
86 backup/encrypt \
87 backup/exclude \
88- backup/full \
89 backup/mkdir \
90 backup/permissions \
91 backup/quiescent \
92
93=== removed file 'tests/backup/full'
94--- tests/backup/full 2011-12-06 15:20:21 +0000
95+++ tests/backup/full 1970-01-01 00:00:00 +0000
96@@ -1,89 +0,0 @@
97-#!/usr/bin/env python
98-# -*- Mode: Python; indent-tabs-mode: nil; tab-width: 2; coding: utf-8 -*-
99-#
100-# This file is part of Déjà Dup.
101-# For copyright information, see AUTHORS.
102-#
103-# Déjà Dup is free software; you can redistribute it and/or modify
104-# it under the terms of the GNU General Public License as published by
105-# the Free Software Foundation; either version 3 of the License, or
106-# (at your option) any later version.
107-#
108-# Déjà Dup is distributed in the hope that it will be useful, but
109-# WITHOUT ANY WARRANTY; without even the implied warranty of
110-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
111-# General Public License for more details.
112-#
113-# You should have received a copy of the GNU General Public License
114-# along with Déjà Dup. If not, see <http://www.gnu.org/licenses/>.
115-
116-# Test whether we correctly switch to full backup mode vs incremental
117-
118-import sys
119-sys.path.insert(0, sys.path[0]+'/..')
120-import base
121-import ldtp
122-
123-max_allowed = 24 * 7
124-scale = 12
125-
126-def max_inc():
127- base.setup()
128- base.backup_simple(backend='file', encrypt=False, includes=['data/simple'])
129- # Change date to maximum allowed incremental, confirm next is incremental
130- base.last_date_change('%d days ago' % (max_allowed))
131- base.backup_simple(encrypt=None)
132- assert base.last_type() == 'inc', base.list_manifests()
133-
134-def max_full():
135- base.setup()
136- base.backup_simple(backend='file', encrypt=False, includes=['data/simple'])
137- # Change date to maximum allowed incremental+1, confirm next is full
138- base.last_date_change('%d days ago' % (max_allowed+1))
139- base.backup_simple(encrypt=None)
140- assert base.last_type() == 'full', base.list_manifests()
141-
142-def half_inc():
143- base.setup()
144- base.set_settings_value("delete-after", '80')
145- base.backup_simple(backend='file', encrypt=False, includes=['data/simple'])
146- # Change date to maximum allowed incremental, confirm next is inc
147- base.last_date_change('%d days ago' % (40))
148- base.backup_simple(encrypt=None)
149- assert base.last_type() == 'inc', base.list_manifests()
150-
151-def half_full():
152- base.setup()
153- base.set_settings_value("delete-after", '80')
154- base.backup_simple(backend='file', encrypt=False, includes=['data/simple'])
155- # Change date to maximum allowed incremental+1, confirm next is full
156- base.last_date_change('%d days ago' % (41))
157- base.backup_simple(encrypt=None)
158- assert base.last_type() == 'full', base.list_manifests()
159-
160-def period_inc():
161- base.setup()
162- base.set_settings_value("periodic", 'true')
163- base.set_settings_value("periodic-period", '7')
164- base.backup_simple(backend='file', encrypt=False, includes=['data/simple'])
165- # Change date to maximum allowed incremental, confirm next is inc
166- base.last_date_change('%d days ago' % (7*scale))
167- base.backup_simple(encrypt=None)
168- assert base.last_type() == 'inc', base.list_manifests()
169-
170-def period_full():
171- base.setup()
172- base.set_settings_value("periodic", 'true')
173- base.set_settings_value("periodic-period", '7')
174- base.backup_simple(backend='file', encrypt=False, includes=['data/simple'])
175- # Change date to maximum allowed incremental+1, confirm next is full
176- base.last_date_change('%d days ago' % ((7*scale)+1))
177- base.backup_simple(encrypt=None)
178- assert base.last_type() == 'full', base.list_manifests()
179-
180-base.run(max_inc)
181-base.run(max_full)
182-base.run(half_inc)
183-base.run(half_full) # optimism!
184-base.run(period_inc)
185-base.run(period_full)
186
187=== added file 'tests/scripts/threshold-full.test'
188--- tests/scripts/threshold-full.test 1970-01-01 00:00:00 +0000
189+++ tests/scripts/threshold-full.test 2012-06-21 17:50:33 +0000
190@@ -0,0 +1,15 @@
191+# Confirm that we are doing the right thing with full backup thresholds.
192+# Specifically, that when we are right over the threshold, we do a full backup.
193+
194+[Operation]
195+Type=backup
196+IsFull=true
197+
198+[Duplicity]
199+Runs=status;dry;backup;
200+
201+[Duplicity status]
202+#echo "INFO 3"
203+#echo "chain-complete"
204+#echo " full $(date --utc --date='91 days ago' +%Y%m%dT%H%M%SZ) 1 enc"
205+OutputScript=true
206
207=== added file 'tests/scripts/threshold-inc.test'
208--- tests/scripts/threshold-inc.test 1970-01-01 00:00:00 +0000
209+++ tests/scripts/threshold-inc.test 2012-06-21 17:50:33 +0000
210@@ -0,0 +1,16 @@
211+# Confirm that we are doing the right thing with full backup thresholds.
212+# Specifically, that when we are right under the threshold, we still do an
213+# incremental.
214+
215+[Operation]
216+Type=backup
217+IsFull=false
218+
219+[Duplicity]
220+Runs=status;dry;backup;
221+
222+[Duplicity status]
223+#echo "INFO 3"
224+#echo "chain-complete"
225+#echo " full $(date --utc --date='90 days ago' +%Y%m%dT%H%M%SZ) 1 enc"
226+OutputScript=true
227
228=== modified file 'widgets/ConfigDelete.vala'
229--- widgets/ConfigDelete.vala 2011-10-27 15:38:04 +0000
230+++ widgets/ConfigDelete.vala 2012-06-21 17:50:33 +0000
231@@ -23,9 +23,6 @@
232
233 public class ConfigDelete : ConfigChoice
234 {
235- public static const int MONTHLY = 28;
236- public static const int BIMONTHLY = 28*2;
237- public static const int TRIMONTHLY = 28*3;
238 public static const int SEMIANNUALLY = 365/2;
239 public static const int ANNUALLY = 365;
240 public static int FOREVER = int.MAX;
241@@ -40,9 +37,6 @@
242 Gtk.TreeIter iter;
243 int i = 0;
244
245- store.insert_with_values(out iter, i++, 0, _("At least a month"), 1, MONTHLY);
246- store.insert_with_values(out iter, i++, 0, _("At least two months"), 1, BIMONTHLY);
247- store.insert_with_values(out iter, i++, 0, _("At least three months"), 1, TRIMONTHLY);
248 store.insert_with_values(out iter, i++, 0, _("At least six months"), 1, SEMIANNUALLY);
249 store.insert_with_values(out iter, i++, 0, _("At least a year"), 1, ANNUALLY);
250 store.insert_with_values(out iter, i++, 0, _("Forever"), 1, FOREVER);
251
252=== modified file 'widgets/ConfigLabelPolicy.vala'
253--- widgets/ConfigLabelPolicy.vala 2011-10-31 13:15:46 +0000
254+++ widgets/ConfigLabelPolicy.vala 2012-06-21 17:50:33 +0000
255@@ -60,13 +60,7 @@
256 if (delete_after <= 0)
257 delete_after = ConfigDelete.FOREVER;
258
259- if (delete_after == ConfigDelete.MONTHLY)
260- policy = _("Old backups will be kept for at least a month or until the backup location is low on space.");
261- else if (delete_after == ConfigDelete.BIMONTHLY)
262- policy = _("Old backups will be kept for at least two months or until the backup location is low on space.");
263- else if (delete_after == ConfigDelete.TRIMONTHLY)
264- policy = _("Old backups will be kept for at least three months or until the backup location is low on space.");
265- else if (delete_after == ConfigDelete.SEMIANNUALLY)
266+ if (delete_after == ConfigDelete.SEMIANNUALLY)
267 policy = _("Old backups will be kept for at least six months or until the backup location is low on space.");
268 else if (delete_after == ConfigDelete.ANNUALLY)
269 policy = _("Old backups will be kept for at least a year or until the backup location is low on space.");
270
271=== modified file 'widgets/ConfigPeriod.vala'
272--- widgets/ConfigPeriod.vala 2011-10-07 14:43:17 +0000
273+++ widgets/ConfigPeriod.vala 2012-06-21 17:50:33 +0000
274@@ -35,8 +35,6 @@
275
276 store.insert_with_values(out iter, i++, 0, _("Daily"), 1, 1);
277 store.insert_with_values(out iter, i++, 0, _("Weekly"), 1, 7);
278- store.insert_with_values(out iter, i++, 0, _("Every 2 weeks"), 1, 14);
279- store.insert_with_values(out iter, i++, 0, _("Monthly"), 1, 28);
280
281 store.set_sort_column_id(1, Gtk.SortType.ASCENDING);
282

Subscribers

People subscribed via source and target branches