Martin Wilck has proposed merging lp:~mwilck/duplicity/0.7-series into 

Requested reviews:
  duplicity-team (duplicity-team)

For more details, see:

GPG: enable truly non-interactive operation with gpg2

This patch fixes the IMO unexpected behavior that, when using GnuPG2, a pass 
phrase dialog always pops up for saving backups. This is particularly annoying 
when trying to do unattended / fully automatic backups.

The patch changes the behavior of the "--use-agent" option when GnuPG 2 is in 
use. The man page is updated accordingly. I am not sure if this would be too 
disruptive a change for the stable series. However I think this is a real 
improvement, even if some users of duplicity with gpg2 may need to change their 
command lines.

Successful builds for Trusty and Xenial under

Your team duplicity-team is requested to review the proposed merge of 
lp:~mwilck/duplicity/0.7-series into lp:duplicity/0.7-series.
=== modified file 'bin/duplicity.1'
--- bin/duplicity.1	2016-08-22 10:59:00 +0000
+++ bin/duplicity.1	2016-09-21 13:17:18 +0000
@@ -917,9 +917,15 @@
 if needed.
 .B Note:
-GnuPG 2 and newer ignore this option and will always use a running
-.B gpg-agent
-if no passphrase was delivered.
+Contrary to previous versions of duplicity, this option will also be honored
+by GnuPG 2 and newer versions. If GnuPG 2 is in use, duplicity passes the option
+.I --pinentry-mode=cancel
+to the the gpg process unless
+.I --use-agent
+is specified on the duplicity command line. This has the effect that GnuPG 2
+uses the agent only if
+.I --use-agent
+is given, just like GnuPG 1.
 .BI "--verbosity " level ", -v" level

=== modified file 'duplicity/'
--- duplicity/	2015-11-05 15:36:58 +0000
+++ duplicity/	2016-09-21 13:17:18 +0000
@@ -87,6 +87,20 @@
             self.hidden_recipients = []
+        self.gpg_major = self.get_gpg_major(globals.gpg_binary)
+    _version_re = re.compile(r'^gpg.*\(GnuPG\) (?P<maj>[0-9])\.[0-9]+\.[0-9]+$')
+    def get_gpg_major(self, binary):
+        gpg = gpginterface.GnuPG()
+        if binary is not None:
+   = binary
+        res =["--version"], create_fhs=["stdout"])
+        line = res.handles["stdout"].readline().rstrip()
+        mtc =
+        if mtc is not None:
+            return int("maj"), 10)
+        raise GPGError("failed to determine gpg version of %s from %s" % (binary, line))
 class GPGFile:
@@ -121,6 +135,10 @@
         if globals.use_agent:
+        elif profile.gpg_major == 2:
+            # This forces gpg2 to ignore the agent.
+            # Necessary to enforce truly non-interactive operation.
+            gnupg.options.extra_args.append('--pinentry-mode=cancel')
         if globals.gpg_options:
             for opt in globals.gpg_options.split():

Mailing list:
Post to     :
Unsubscribe :
More help   :

Reply via email to