On Mon, May 03, 2010 at 09:51:10AM +0200, Olivier Berger wrote:
> 
> FYI, I'm using this modified version of duplicity locally, and have generated 
> a modified Debian package.
> 
> Here's in attachment the diff on the source package.
> 

FYI, this used to break remove-older-than command, so I generated a new 
version. Here's the updated interdiff in attachment.

Best regards,
diff -u duplicity-0.6.08b/debian/changelog duplicity-0.6.08b/debian/changelog
--- duplicity-0.6.08b/debian/changelog
+++ duplicity-0.6.08b/debian/changelog
@@ -1,3 +1,17 @@
+duplicity (0.6.08b-1.2) unstable; urgency=low
+
+  * Fix 04_remove_all_inc_of_but_n_full.dpatch to not break
+    remove-older-than.
+
+ -- Olivier Berger <olivier.ber...@it-sudparis.eu>  Sun, 16 May 2010 10:14:05 +0200
+
+duplicity (0.6.08b-1.1) UNRELEASED; urgency=low
+
+  * Add patch to add option to remove old incremental backups from target
+    (Closes: #579966).
+
+ -- Olivier Berger <olivier.ber...@it-sudparis.eu>  Mon, 03 May 2010 08:27:59 +0200
+
 duplicity (0.6.08b-1) unstable; urgency=low
 
   * New upstream release
diff -u duplicity-0.6.08b/debian/patches/00list duplicity-0.6.08b/debian/patches/00list
--- duplicity-0.6.08b/debian/patches/00list
+++ duplicity-0.6.08b/debian/patches/00list
@@ -3,0 +4 @@
+04_remove_all_inc_of_but_n_full
only in patch2:
unchanged:
--- duplicity-0.6.08b.orig/debian/patches/04_remove_all_inc_of_but_n_full.dpatch
+++ duplicity-0.6.08b/debian/patches/04_remove_all_inc_of_but_n_full.dpatch
@@ -0,0 +1,195 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 04_remove_all_inc_of_but_n_full.dpatch by Olivier Berger <olivier.ber...@it-sudparis.eu>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Add remove-all-inc-of-but-n-full option (#579966)
+
+...@dpatch@
+
+diff -urNad duplicity-0.6.08b.orig//duplicity duplicity-0.6.08b/duplicity
+--- duplicity-0.6.08b.orig//duplicity	2010-03-12 02:39:07.000000000 +0100
++++ duplicity-0.6.08b/duplicity	2010-05-03 08:57:09.000000000 +0200
+@@ -98,6 +98,7 @@
+     elif action in ["collection-status",
+                     "remove-old",
+                     "remove-all-but-n-full",
++                    "remove-all-inc-of-but-n-full",
+                     ]:
+         return ""
+ 
+@@ -763,14 +763,20 @@
+                                     "Deleting backup sets at times:",
+                                     len(setlist)) +
+                    "\n" + set_times_str(setlist))
+-        if globals.dry_run:
+-            col_stats.set_values(sig_chain_warning=None)
+-        else:
+-            setlist.reverse() # save oldest for last
+-            for set in setlist:
+-                set.delete()
+-            col_stats.set_values(sig_chain_warning=None)
++        setlist.reverse() # save oldest for last
++        for set in setlist:
++            # if remove_all_inc_of_but_n_full_mode mode, remove only incrementals one and not full
++            if globals.dry_run:
++                log.Notice("(Not: dry-run) Deleting set " + set.type + " " + dup_time.timetopretty(set.get_time()))
++            else:
++                if globals.remove_all_inc_of_but_n_full_mode and (set.type != "inc") :
++                    log.Notice("Not deleting set " + set.type + " " + dup_time.timetopretty(set.get_time()))
++                else :
++                    log.Notice("Deleting set " + set.type + " " + dup_time.timetopretty(set.get_time()))
++                    set.delete()
++        col_stats.set_values(sig_chain_warning=None)
+ 
++        if not globals.dry_run:
+             # force a cleanup operation to get rid of unnecessary old cruft
+             # we said we want to remove them! didn't we, huh?
+             # bad duplicity, bad doggy!
+@@ -1194,7 +1200,7 @@
+         cleanup(col_stats)
+     elif action == "remove-old":
+         remove_old(col_stats)
+-    elif action == "remove-all-but-n-full":
++    elif action == "remove-all-but-n-full" or action == "remove-all-inc-of-but-n-full":
+         remove_all_but_n_full(col_stats)
+     elif action == "sync":
+         sync_archive(col_stats)
+diff -urNad duplicity-0.6.08b.orig//duplicity.1 duplicity-0.6.08b/duplicity.1
+--- duplicity-0.6.08b.orig//duplicity.1	2010-03-12 02:39:07.000000000 +0100
++++ duplicity-0.6.08b/duplicity.1	2010-05-03 08:57:09.000000000 +0200
+@@ -53,6 +53,12 @@
+ .BI [ --force ]
+ .I target_url
+ 
++.B duplicity remove-all-inc-of-but-n-full
++.I count
++.BI [ options ]
++.BI [ --force ]
++.I target_url
++
+ .SH DESCRIPTION
+ Duplicity incrementally backs up files and directory
+ by encrypting tar-format volumes with GnuPG and uploading them to a
+@@ -196,6 +202,16 @@
+ .I --force
+ will be needed to delete the files rather than just list them.
+ 
++.TP
++.BI "remove-all-inc-of-but-n-full " count
++Delete incremental sets of all backups sets that are older than the count:th last full
++backup (in other words, keep only old full backups and not their increments).
++.I count
++must be larger than zero. A value of 1 means that only the single most
++recent backup chain will be kept intact.  Note that
++.I --force
++will be needed to delete the files rather than just list them.
++
+ .TP
+ .B verify
+ Enter verify mode instead of restore.  If the --file-to-restore option
+diff -urNad duplicity-0.6.08b.orig//src/collections.py duplicity-0.6.08b/src/collections.py
+--- duplicity-0.6.08b.orig//src/collections.py	2010-03-12 02:39:06.000000000 +0100
++++ duplicity-0.6.08b/src/collections.py	2010-05-03 08:57:09.000000000 +0200
+@@ -1081,7 +1081,7 @@
+         Furthermore, none of the times will be of a set which a newer
+         set may depend on.  For instance, if set A is a full set older
+         than t, and set B is an incremental based on A which is newer
+-        than tt, then the time of set A will not be returned.
++        than t, then the time of set A will not be returned.
+         """
+         old_sets = []
+         for chain in self.get_chains_older_than(t):
+diff -urNad duplicity-0.6.08b.orig//src/commandline.py duplicity-0.6.08b/src/commandline.py
+--- duplicity-0.6.08b.orig//src/commandline.py	2010-03-12 02:39:06.000000000 +0100
++++ duplicity-0.6.08b/src/commandline.py	2010-05-03 08:57:09.000000000 +0200
+@@ -58,6 +58,7 @@
+             "list-current-files",
+             "remove-older-than",
+             "remove-all-but-n-full",
++            "remove-all-inc-of-but-n-full",
+             "restore",
+             "verify",
+             ]
+@@ -504,14 +505,18 @@
+             command_line_error("Missing time string for remove-older-than")
+         globals.remove_time = dup_time.genstrtotime(arg)
+         num_expect = 1
+-    elif cmd == "remove-all-but-n-full":
++    elif cmd == "remove-all-but-n-full" or cmd == "remove-all-inc-of-but-n-full":
++        if cmd == "remove-all-but-n-full" :
++            globals.remove_all_but_n_full_mode = True
++        if cmd == "remove-all-inc-of-but-n-full" :
++            globals.remove_all_inc_of_but_n_full_mode = True
+         try:
+             arg = args.pop(0)
+         except:
+-            command_line_error("Missing count for remove-all-but-n-full")
++            command_line_error("Missing count for " + cmd)
+         globals.keep_chains = int(arg)
+         if not globals.keep_chains > 0:
+-            command_line_error("remove-all-but-n-full count must be > 0")
++            command_line_error(cmd + " count must be > 0")
+         num_expect = 1
+     elif cmd == "verify":
+         verify = True
+@@ -699,6 +704,7 @@
+   duplicity cleanup [%(options)s] %(target_url)s
+   duplicity remove-older-than %(time)s [%(options)s] %(target_url)s
+   duplicity remove-all-but-n-full %(count)s [%(options)s] %(target_url)s
++  duplicity remove-all-inc-of-but-n-full %(count)s [%(options)s] %(target_url)s
+ 
+ """ % dict
+ 
+@@ -732,6 +738,7 @@
+   restore <%(target_url)s> <%(source_dir)s>
+   remove-older-than <%(time)s> <%(target_url)s>
+   remove-all-but-n-full <%(count)s> <%(target_url)s>
++  remove-all-inc-of-but-n-full <%(count)s> <%(target_url)s>
+   verify <%(target_url)s> <%(source_dir)s>""" % dict
+ 
+     return msg
+@@ -842,7 +849,7 @@
+                 n+=1
+         assert n <= 1, "Invalid syntax, two conflicting modes specified"
+     if action in ["list-current", "collection-status",
+-                  "cleanup", "remove-old", "remove-all-but-n-full"]:
++                  "cleanup", "remove-old", "remove-all-but-n-full", "remove-all-inc-of-but-n-full"]:
+         assert_only_one([list_current, collection_status, cleanup,
+                          globals.remove_time is not None])
+     elif action == "restore" or action == "verify":
+@@ -893,8 +900,10 @@
+             action = "cleanup"
+         elif globals.remove_time is not None:
+             action = "remove-old"
+-        elif globals.keep_chains is not None:
++        elif globals.remove_all_but_n_full_mode:
+             action = "remove-all-but-n-full"
++        elif globals.remove_all_inc_of_but_n_full_mode:
++            action = "remove-all-inc-of-but-n-full"
+         else:
+             command_line_error("Too few arguments")
+         globals.backend = backend.get_backend(args[0])
+
+diff -urNad duplicity-0.6.08b.orig//src/globals.py duplicity-0.6.08b/src/globals.py
+--- duplicity-0.6.08b.orig//src/globals.py	2010-03-12 02:39:06.000000000 +0100
++++ duplicity-0.6.08b/src/globals.py	2010-05-03 08:57:09.000000000 +0200
+@@ -107,10 +107,16 @@
+ # be deleted.
+ remove_time = None
+ 
+-# If set, signifies the number of backups chains to keep when perfroming
+-# a --remove-all-but-n-full.
++# If set, signifies the number of backups chains to keep when performing
++# a remove-all-but-n-full.
+ keep_chains = None
+ 
++# If set, signifies that remove-all-but-n-full in progress
++remove_all_but_n_full_mode = None
++
++# If set, signifies that remove-all-inc-of-but-n-full in progress (variant of remove-all-but-n-full)
++remove_all_inc_of_but_n_full_mode = None
++
+ # Don't actually do anything, but still report what would be done
+ dry_run = False
+ 
+

Reply via email to