Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 649276 - sys-apps/portage: gpg key refresh needs exponential backoff with jitter
Summary: sys-apps/portage: gpg key refresh needs exponential backoff with jitter
Status: RESOLVED FIXED
Alias: None
Product: Portage Development
Classification: Unclassified
Component: Core - Interface (emerge) (show other bugs)
Hardware: All All
: Normal normal
Assignee: Portage team
URL:
Whiteboard:
Keywords: InVCS
Depends on:
Blocks: 240187 650144 647696 651804
  Show dependency tree
 
Reported: 2018-03-01 21:57 UTC by Zac Medico
Modified: 2018-07-08 19:37 UTC (History)
4 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Zac Medico gentoo-dev 2018-03-01 21:57:55 UTC
There are multiple reports of intermittent key refresh failures, and gemato has no retry support (see bug 649254):

bug 647696

bug 648586

https://forums.gentoo.org/viewtopic-p-8179992.html#8179992

https://forums.gentoo.org/viewtopic-p-8185252.html#8185252

https://forums.gentoo.org/viewtopic-p-8188376.html#8188376

https://forums.gentoo.org/viewtopic-p-8190196.html#8190196


There's an example backoff library here which supports both synchronous calls and coroutines:

https://pypi.python.org/pypi/backoff
https://github.com/litl/backoff
Comment 1 Zac Medico gentoo-dev 2018-03-03 08:56:32 UTC
The sync code runs in a fork since bug 557426, and the asyncio currently does not support running the event loop in a fork, see https://bugs.python.org/issue21998. Therefore, the backoff code should not rely on an event loop if it is to be compatible with asyncio (bug 591760).
Comment 2 Zac Medico gentoo-dev 2018-03-04 00:26:40 UTC
Since portage has a lot of code already running in forks that relies on event loops, I suppose it's fine for the sync backoff code to rely on an event loop. In fact, I've found this workaround for asyncio that I've posted on the upstream issue:

> # https://bugs.python.org/issue21998#msg313196
> 
> _default_policy = asyncio.get_event_loop_policy()
> _pid_loop = {}
> 
> class MultiprocessingPolicy(asyncio.AbstractEventLoopPolicy):
>     def get_event_loop(self):
>         pid = os.getpid()
>         loop = _pid_loop.get(pid)
>         if loop is None:
>             loop = self.new_event_loop()
>             _pid_loop[pid] = loop
>         return loop
> 
>     def new_event_loop(self):
>         return _default_policy.new_event_loop()
> 
> asyncio.set_event_loop_policy(MultiprocessingPolicy())
Comment 3 Larry the Git Cow gentoo-dev 2018-03-09 23:28:04 UTC
The bug has been referenced in the following commit(s):

https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=369f75c043173531d52a4aa6c7ba55e5a8d5b1ac

commit 369f75c043173531d52a4aa6c7ba55e5a8d5b1ac
Author:     Zac Medico <zmedico@gentoo.org>
AuthorDate: 2018-03-09 23:23:01 +0000
Commit:     Zac Medico <zmedico@gentoo.org>
CommitDate: 2018-03-09 23:27:56 +0000

    sys-apps/portage: rsync-verify off by default (bug 649276)
    
    Since portage-2.3.24 is due for stabilization, and rsync-verify support
    is not really stable yet, turn it off by default.
    
    Bug: https://bugs.gentoo.org/649276
    See: https://bugs.gentoo.org/647964
    Package-Manager: Portage-2.3.24, Repoman-2.3.6

 sys-apps/portage/portage-2.3.24-r1.ebuild | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)}
Comment 4 Larry the Git Cow gentoo-dev 2018-03-09 23:37:05 UTC
The bug has been referenced in the following commit(s):

https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=9c860bd224915e7a7e94915a36629174a783f749

commit 9c860bd224915e7a7e94915a36629174a783f749
Author:     Zac Medico <zmedico@gentoo.org>
AuthorDate: 2018-03-09 23:34:16 +0000
Commit:     Zac Medico <zmedico@gentoo.org>
CommitDate: 2018-03-09 23:36:58 +0000

    profiles/base: Stable-mask sys-apps/portage[rsync-verify]
    
    Bug: https://bugs.gentoo.org/649276

 profiles/base/package.use.stable.mask | 5 +++++
 1 file changed, 5 insertions(+)}
Comment 5 Zac Medico gentoo-dev 2018-03-29 09:00:47 UTC
I have a working retry decorator, using futures, with API similar to tenacity:

https://github.com/zmedico/portage/tree/asyncio-bug_649276

Now I only need to put this to use for the gpg key refresh, and add a few repos.conf configuration options to control it.
Comment 7 Larry the Git Cow gentoo-dev 2018-04-02 17:11:44 UTC
The bug has been referenced in the following commit(s):

https://gitweb.gentoo.org/proj/portage.git/commit/?id=5f29f03d0d9714082fabbbae5cead8857fbc9093

commit 5f29f03d0d9714082fabbbae5cead8857fbc9093
Author:     Zac Medico <zmedico@gentoo.org>
AuthorDate: 2018-03-30 08:12:19 +0000
Commit:     Zac Medico <zmedico@gentoo.org>
CommitDate: 2018-04-02 16:53:24 +0000

    rsync: add key refresh retry (bug 649276)
    
    Since key refresh is prone to failure, retry using exponential
    backoff with random jitter. This adds the following sync-openpgp-*
    configuration settings:
    
    sync-openpgp-key-refresh-retry-count = 40
    
      Maximum number of times to retry key refresh if it fails.  Between
      each  key  refresh attempt, there is an exponential delay with a
      constant multiplier and a uniform random multiplier between 0 and 1.
    
    sync-openpgp-key-refresh-retry-delay-exp-base = 2
    
      The base of the exponential expression. The exponent is the number
      of previous refresh attempts.
    
    sync-openpgp-key-refresh-retry-delay-max = 60
    
      Maximum  delay between each retry attempt, in units of seconds. This
      places a limit on the length of the exponential delay.
    
    sync-openpgp-key-refresh-retry-delay-mult = 4
    
      Multiplier for the exponential delay.
    
    sync-openpgp-key-refresh-retry-overall-timeout = 1200
    
      Combined time limit for all refresh attempts, in units of seconds.
    
    Bug: https://bugs.gentoo.org/649276

 cnf/repos.conf                          |  5 ++
 man/portage.5                           | 21 +++++++-
 pym/portage/repository/config.py        | 22 +++++++++
 pym/portage/sync/modules/rsync/rsync.py | 16 +++++-
 pym/portage/sync/syncbase.py            | 87 ++++++++++++++++++++++++++++++++-
 5 files changed, 146 insertions(+), 5 deletions(-)

https://gitweb.gentoo.org/proj/portage.git/commit/?id=1aa9a71731f3ab05e10190493956c70998abf12a

commit 1aa9a71731f3ab05e10190493956c70998abf12a
Author:     Zac Medico <zmedico@gentoo.org>
AuthorDate: 2018-03-16 19:37:54 +0000
Commit:     Zac Medico <zmedico@gentoo.org>
CommitDate: 2018-04-02 16:53:24 +0000

    Add retry decorator (API inspired by tenacity)
    
    This decorator will be useful for retrying asynchronous
    operations, such as gpg key refresh (bug 649276). The
    API is inspired by tenacity, but is simpler. Only
    asynchronous functions (like @asyncio.coroutine functions)
    are supported. In order to retry a synchronous function,
    first convert it to an asynchronous function as follows:
    
        asynchronous_func = functools.partial(
            loop.run_in_executor, None, synchronous_func)
    
    Bug: https://bugs.gentoo.org/649276
    See: https://github.com/jd/tenacity
    Reviewed-by: Alec Warner <antarus@gentoo.org>

 pym/portage/tests/util/futures/test_retry.py | 147 +++++++++++++++++++++
 pym/portage/util/futures/futures.py          |   6 +
 pym/portage/util/futures/retry.py            | 183 +++++++++++++++++++++++++++
 3 files changed, 336 insertions(+)}
Comment 8 Larry the Git Cow gentoo-dev 2018-04-04 18:53:34 UTC
The bug has been referenced in the following commit(s):

https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=2edaa0b0321a8378d88f8852507648c05f85fcc2

commit 2edaa0b0321a8378d88f8852507648c05f85fcc2
Author:     Zac Medico <zmedico@gentoo.org>
AuthorDate: 2018-04-04 18:52:00 +0000
Commit:     Zac Medico <zmedico@gentoo.org>
CommitDate: 2018-04-04 18:53:26 +0000

    profiles/base: Stable-mask <sys-apps/portage-2.3.28[rsync-verify]
    
    Retry support for key refresh is implemented in portage-2.3.28.
    
    Bug: https://bugs.gentoo.org/649276

 profiles/base/package.use.stable.mask | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)}
Comment 9 Zac Medico gentoo-dev 2018-07-02 18:45:00 UTC
Fixed in portage-2.3.40-r1.