From 1c80f506db9ee3b660b0e1177de2afdb494c3685 Mon Sep 17 00:00:00 2001 From: Antoine Musso Date: Mon, 5 Mar 2018 11:17:19 +0100 Subject: [PATCH] Import Zuul modules at top of files We had to make sure to not import Paramiko before daemonization. The zuul-server would hang when establishing a Gerrit ssh connection due to Random.Crypto() failling to acquire random number from /dev/urandom. It would block on read() and never process. When the Server command line invokes the daemonization, python-daemon closes all file descriptors. Including /dev/urandom. Then the daemonized establishes the SSH connection and fails to get random number because Random.Crypto() locks on read() on a closed file description. Paramiko issue is https://github.com/paramiko/paramiko/issues/59 and the fix is to use os.random: https://github.com/paramiko/paramiko/commit/6f211115f49edcea7d23b764d7cf3a84ff12f5f0 That has been released with Paramiko 1.11.6 and we now require 2.0+. Move Zuul imports at top of files and drop the comments hinting at the Paramiko bug. Change-Id: I5fe956df74815761e3eac2bd25f6fd7f167fc854 --- zuul/cmd/__init__.py | 5 ----- zuul/cmd/executor.py | 6 +----- zuul/cmd/merger.py | 7 ------- zuul/cmd/scheduler.py | 19 ++++++------------- 4 files changed, 7 insertions(+), 30 deletions(-) diff --git a/zuul/cmd/__init__.py b/zuul/cmd/__init__.py index 6ab759833b..ee73386f09 100755 --- a/zuul/cmd/__init__.py +++ b/zuul/cmd/__init__.py @@ -40,11 +40,6 @@ from zuul.ansible import logconfig import zuul.lib.connections from zuul.lib.config import get_default -# Do not import modules that will pull in paramiko which must not be -# imported until after the daemonization. -# https://github.com/paramiko/paramiko/issues/59 -# Similar situation with gear and statsd. - def stack_dump_handler(signum, frame): signal.signal(signal.SIGUSR2, signal.SIG_IGN) diff --git a/zuul/cmd/executor.py b/zuul/cmd/executor.py index b050a5979c..5e5ea377d2 100755 --- a/zuul/cmd/executor.py +++ b/zuul/cmd/executor.py @@ -22,12 +22,8 @@ import tempfile import zuul.cmd import zuul.executor.server -from zuul.lib.config import get_default -# No zuul imports that pull in paramiko here; it must not be -# imported until after the daemonization. -# https://github.com/paramiko/paramiko/issues/59 -# Similar situation with gear and statsd. +from zuul.lib.config import get_default class Executor(zuul.cmd.ZuulDaemonApp): diff --git a/zuul/cmd/merger.py b/zuul/cmd/merger.py index 8c4798923c..1d4b6fefff 100755 --- a/zuul/cmd/merger.py +++ b/zuul/cmd/merger.py @@ -20,11 +20,6 @@ import sys import zuul.cmd import zuul.merger.server -# No zuul imports here because they pull in paramiko which must not be -# imported until after the daemonization. -# https://github.com/paramiko/paramiko/issues/59 -# Similar situation with gear and statsd. - class Merger(zuul.cmd.ZuulDaemonApp): app_name = 'merger' @@ -48,8 +43,6 @@ class Merger(zuul.cmd.ZuulDaemonApp): sys.exit(0) def run(self): - # See comment at top of file about zuul imports - import zuul.merger.server if self.args.command in zuul.merger.server.COMMANDS: self.send_command(self.args.command) sys.exit(0) diff --git a/zuul/cmd/scheduler.py b/zuul/cmd/scheduler.py index a3a53cfe89..c782d4a68b 100755 --- a/zuul/cmd/scheduler.py +++ b/zuul/cmd/scheduler.py @@ -20,14 +20,14 @@ import sys import signal import zuul.cmd +import zuul.executor.client +import zuul.merger.client +import zuul.nodepool +import zuul.scheduler +import zuul.zk + from zuul.lib.config import get_default from zuul.lib.statsd import get_statsd_config -import zuul.scheduler - -# No zuul imports here because they pull in paramiko which must not be -# imported until after the daemonization. -# https://github.com/paramiko/paramiko/issues/59 -# Similar situation with gear and statsd. class Scheduler(zuul.cmd.ZuulDaemonApp): @@ -111,16 +111,9 @@ class Scheduler(zuul.cmd.ZuulDaemonApp): os.kill(self.gear_server_pid, signal.SIGKILL) def run(self): - # See comment at top of file about zuul imports - import zuul.scheduler if self.args.command in zuul.scheduler.COMMANDS: self.send_command(self.args.command) sys.exit(0) - # See comment at top of file about zuul imports - import zuul.executor.client - import zuul.merger.client - import zuul.nodepool - import zuul.zk if (self.config.has_option('gearman_server', 'start') and self.config.getboolean('gearman_server', 'start')):