From 7ed557c4f7385c9c31d57b4266fe6aace9ca51c5 Mon Sep 17 00:00:00 2001 From: Val V Date: Mon, 2 Oct 2023 06:30:44 -0700 Subject: [PATCH] Fix stealth exceptions and blocking select() in daemonize() (#81064) - 2.15 (#81581) * Fix stealth exceptions and blocking select() in daemonize() (#81064) * Fix stealth exceptions and blocking select() in daemonize() * Add changelog entry (cherry picked from commit 894c339df8113cdb579cd00210f4ed394859a5b1) * Daemonize follow-up fixes (#81584) * Ensure binary data transmission in daemonize * Add changelog fragment (cherry picked from commit 91f94fb59d2ec3e69ff98649094f838c6d81601b) --- changelogs/fragments/81064-daemonize-fixes.yml | 2 ++ .../fragments/81584-daemonize-follow-up-fixes.yml | 2 ++ lib/ansible/module_utils/service.py | 13 ++++++++----- 3 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 changelogs/fragments/81064-daemonize-fixes.yml create mode 100644 changelogs/fragments/81584-daemonize-follow-up-fixes.yml diff --git a/changelogs/fragments/81064-daemonize-fixes.yml b/changelogs/fragments/81064-daemonize-fixes.yml new file mode 100644 index 00000000000000..06f2af3d1e6e78 --- /dev/null +++ b/changelogs/fragments/81064-daemonize-fixes.yml @@ -0,0 +1,2 @@ +bugfixes: + - "``ansible.module_utils.service`` - fix inter-process communication in ``daemonize()``" diff --git a/changelogs/fragments/81584-daemonize-follow-up-fixes.yml b/changelogs/fragments/81584-daemonize-follow-up-fixes.yml new file mode 100644 index 00000000000000..5842a0a37ca395 --- /dev/null +++ b/changelogs/fragments/81584-daemonize-follow-up-fixes.yml @@ -0,0 +1,2 @@ +bugfixes: + - "``ansible.module_utils.service`` - ensure binary data transmission in ``daemonize()``" diff --git a/lib/ansible/module_utils/service.py b/lib/ansible/module_utils/service.py index d2cecd49c55c6c..dab13a3c8327aa 100644 --- a/lib/ansible/module_utils/service.py +++ b/lib/ansible/module_utils/service.py @@ -207,17 +207,20 @@ def daemonize(module, cmd): p = subprocess.Popen(run_cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn=lambda: os.close(pipe[1])) fds = [p.stdout, p.stderr] - # loop reading output till its done + # loop reading output till it is done output = {p.stdout: b(""), p.stderr: b("")} while fds: rfd, wfd, efd = select.select(fds, [], fds, 1) - if (rfd + wfd + efd) or p.poll(): + if (rfd + wfd + efd) or p.poll() is None: for out in list(fds): if out in rfd: data = os.read(out.fileno(), chunk) - if not data: + if data: + output[out] += to_bytes(data, errors=errors) + else: fds.remove(out) - output[out] += b(data) + else: + break # even after fds close, we might want to wait for pid to die p.wait() @@ -246,7 +249,7 @@ def daemonize(module, cmd): data = os.read(pipe[0], chunk) if not data: break - return_data += b(data) + return_data += to_bytes(data, errors=errors) # Note: no need to specify encoding on py3 as this module sends the # pickle to itself (thus same python interpreter so we aren't mixing