in src/watchdog/__init__.py [0:0]
def start_tls_tunnel(child_procs, state, state_file_dir, state_file):
"""
Reads the command from the state file, and uses it to start a subprocess.
This is the command that efs-utils used to spin up the efs-proxy or stunnel process.
We launch the stunnel and efs-proxy process in a process group so that child processes can be easily killed.
:param child_procs: list that contains efs-proxy / stunnel processes that the Watchdog instance has spawned
:param state: the state corresponding to a given mount - the proxy process associated with this mount will be started
:param state_file_dir: the directory where mount state files are stored
:param state_file: this function may rewrite the command used to start up the proxy or stunnel process, and thus needs a handle on the state file to update it.
:return: the pid of the proxy or stunnel process that was spawned
"""
command = state["cmd"]
logging.info('Starting TLS tunnel: "%s"', " ".join(command))
efs_proxy_enabled = command_uses_efs_proxy(command)
command = update_stunnel_command_for_ecs_amazon_linux_2(
command, state, state_file_dir, state_file
)
tunnel = None
try:
tunnel = subprocess.Popen(
command,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
preexec_fn=os.setsid,
close_fds=True,
)
except FileNotFoundError as e:
if efs_proxy_enabled:
logging.warning("Watchdog failed to start efs-proxy due to %s", e)
else:
logging.warning("Watchdog failed to start stunnel due to %s", e)
# https://github.com/kubernetes-sigs/aws-efs-csi-driver/issues/812 It is possible that the stunnel is not
# present anymore and replaced by stunnel5 on AL2, meanwhile watchdog is attempting to restart stunnel for
# mount using old efs-utils based on old state file generated during previous mount, which has stale command
# using stunnel bin. Update the state file if the stunnel does not exist anymore, and use stunnel5 on Al2.
#
if get_system_release_version() in AMAZON_LINUX_2_RELEASE_VERSIONS:
for i in range(len(command)):
if "stunnel" in command[i] and "stunnel-config" not in command[i]:
command[i] = find_command_path(
"stunnel5", STUNNEL_INSTALLATION_MESSAGE
)
break
tunnel = subprocess.Popen(
command,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
preexec_fn=os.setsid,
close_fds=True,
)
state["cmd"] = command
logging.info(
"Rewriting %s with new stunnel cmd: %s for Amazon Linux 2 platform.",
state_file,
" ".join(state["cmd"]),
)
rewrite_state_file(state, state_file_dir, state_file)
# We may have used either stunnel or efs-proxy as the TLS tunnel.
# We want to make it clear in the logs which was used.
tunnel_process_name = "stunnel"
if efs_proxy_enabled:
tunnel_process_name = "efs-proxy"
if tunnel is None or not is_pid_running(tunnel.pid):
fatal_error(
"Failed to initialize %s for %s" % (tunnel_process_name, state_file),
"Failed to start %s." % tunnel_process_name,
)
fatal_error(
"Failed to initialize %s for %s" % (tunnel_process_name, state_file),
"Failed to start %s." % tunnel_process_name,
)
logging.info("Started %s, pid: %d", tunnel_process_name, tunnel.pid)
child_procs.append(tunnel)
return tunnel.pid