Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions node_cli/core/ssl/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import time
import socket
import logging
import subprocess
from contextlib import contextmanager

from node_cli.core.ssl.utils import detached_subprocess
Expand Down Expand Up @@ -201,8 +202,15 @@ def check_ssl_connection(host, port, silent=False):
]
expose_output = not silent
with detached_subprocess(ssl_check_cmd, expose_output=expose_output) as dp:
time.sleep(1)
code = dp.poll()
if code is not None:
logger.error('Healthcheck connection failed')
raise SSLHealthcheckError('OpenSSL connection verification failed')
timeout = 20
try:
dp.wait(timeout=timeout)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This consistently times out :/

Based on https://docs.python.org/3/library/subprocess.html#subprocess.Popen.wait I suspect:

Note This will deadlock when using stdout=PIPE or stderr=PIPE and the child process generates enough output to a pipe such that it blocks waiting for the OS pipe buffer to accept more data. Use Popen.communicate() when using pipes to avoid that.

@kucharskim kucharskim Jun 23, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading now https://docs.python.org/3/library/subprocess.html#subprocess.Popen.communicate

communicate() returns a tuple (stdout_data, stderr_data).

and looking how def detached_subprocess() is defined in core/ssl/utils.py, that it is p.stdout.read() and grabs the output, I am inclined to actually lave the loop and dp.poll() as it was.

@kucharskim kucharskim Jun 23, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With dp.wait() it consistently throws subprocess.TimeoutExpired and openssl s_client -connect 127.0.0.1:4536 -verify_return_error -verify 2 is not finishing, but it is running.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm.. it times out for me now with dp.poll() as well, but it worked before 🤔

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I think there were two problems and another fix was stdin=subprocess.DEVNULL in utils.py

except subprocess.TimeoutExpired:
logger.error('Healthcheck timed-out after %s s', timeout)
raise SSLHealthcheckError('OpenSSL connection verification timed-out')

if dp.returncode == 0: # success
return

logger.error('Healthcheck connection failed (code %s)', dp.returncode)
raise SSLHealthcheckError('OpenSSL connection verification failed')
2 changes: 1 addition & 1 deletion node_cli/core/ssl/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def detached_subprocess(cmd, expose_output=False):
logger.debug(f'Starting detached subprocess: {cmd}')
p = subprocess.Popen(
cmd,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.DEVNULL,
encoding='utf-8'
)
try:
Expand Down