From 2723b9e26a42ca4535557fd2eb1bf2fac16c0cf1 Mon Sep 17 00:00:00 2001 From: Sergey Golitsynskiy Date: Thu, 9 Jun 2022 19:48:09 -0400 Subject: [PATCH 1/6] Display descriptive error message when socket path too long --- gravity/process_manager/supervisor_manager.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/gravity/process_manager/supervisor_manager.py b/gravity/process_manager/supervisor_manager.py index 58aa5ba..81d6df8 100644 --- a/gravity/process_manager/supervisor_manager.py +++ b/gravity/process_manager/supervisor_manager.py @@ -225,7 +225,13 @@ def __supervisord(self): if not self.__supervisord_is_running(): # any time that supervisord is not running, let's rewrite supervisord.conf open(self.supervisord_conf_path, "w").write(SUPERVISORD_CONF_TEMPLATE.format(**format_vars)) - self.__supervisord_popen = subprocess.Popen(supervisord_cmd, env=os.environ) + self.__supervisord_popen = subprocess.Popen(supervisord_cmd, env=os.environ, stderr=subprocess.PIPE) + + output = self.__supervisord_popen.communicate() + socket_error_msg = "socket.error reported AF_UNIX path too long" + if socket_error_msg in str(output[1]): + self._handle_socket_path_error() + rc = self.__supervisord_popen.poll() if rc: error("supervisord exited with code %d" % rc) @@ -243,6 +249,17 @@ def __get_supervisor(self): options.realize(args=["-c", self.supervisord_conf_path]) return supervisorctl.Controller(options).get_supervisor() + def _handle_socket_path_error(self): + msg = f""" + The path to your gravity state directory is too long: "{self.supervisord_conf_dir}". + This path becomes part of a socket address. However, in Unix systems there is a limit to the + length of a socket file path (usually 103-108 bytes). You can choose another path with the + --state-dir option to the Gravity command, or by setting $GRAVITY_STATE_DIR in your + environment: + `galaxy --state-dir /home/shorter-path` or `$GRAVITY_STATE_DIR=/home/shorter-path ./run.sh` + """ + error(msg) + def terminate(self): if self.foreground: # if running in foreground, if terminate is called, then supervisord should've already received a SIGINT From 8e876ed725bf7875993e933f5cf5fe32104482c5 Mon Sep 17 00:00:00 2001 From: Sergey Golitsynskiy Date: Mon, 13 Jun 2022 19:38:58 -0400 Subject: [PATCH 2/6] Try to bind a socket to check path length --- gravity/process_manager/supervisor_manager.py | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/gravity/process_manager/supervisor_manager.py b/gravity/process_manager/supervisor_manager.py index 81d6df8..a735766 100644 --- a/gravity/process_manager/supervisor_manager.py +++ b/gravity/process_manager/supervisor_manager.py @@ -3,6 +3,7 @@ import errno import os import shutil +import socket import subprocess import sys import time @@ -194,6 +195,8 @@ def __init__(self, state_dir=None, start_daemon=True, foreground=False): self.__supervisord_popen = None self.foreground = foreground + self._check_path_length() + if not exists(self.supervisord_conf_dir): os.makedirs(self.supervisord_conf_dir) @@ -227,11 +230,6 @@ def __supervisord(self): open(self.supervisord_conf_path, "w").write(SUPERVISORD_CONF_TEMPLATE.format(**format_vars)) self.__supervisord_popen = subprocess.Popen(supervisord_cmd, env=os.environ, stderr=subprocess.PIPE) - output = self.__supervisord_popen.communicate() - socket_error_msg = "socket.error reported AF_UNIX path too long" - if socket_error_msg in str(output[1]): - self._handle_socket_path_error() - rc = self.__supervisord_popen.poll() if rc: error("supervisord exited with code %d" % rc) @@ -249,6 +247,18 @@ def __get_supervisor(self): options.realize(args=["-c", self.supervisord_conf_path]) return supervisorctl.Controller(options).get_supervisor() + def _check_path_length(self): + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + bind_path = self.supervisord_conf_path + try: + sock.bind(bind_path) + except OSError as e: + if "AF_UNIX path too long" in str(e): + self._handle_socket_path_error() + finally: + sock.close() + os.unlink(bind_path) + def _handle_socket_path_error(self): msg = f""" The path to your gravity state directory is too long: "{self.supervisord_conf_dir}". From 6b5e8dfab8ac15fa7b2744e980533dc3ca560f4d Mon Sep 17 00:00:00 2001 From: John Davis Date: Tue, 14 Jun 2022 13:35:11 -0400 Subject: [PATCH 3/6] Use supervisord_sock_path Co-authored-by: Marius van den Beek --- gravity/process_manager/supervisor_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gravity/process_manager/supervisor_manager.py b/gravity/process_manager/supervisor_manager.py index a735766..c218fd2 100644 --- a/gravity/process_manager/supervisor_manager.py +++ b/gravity/process_manager/supervisor_manager.py @@ -249,7 +249,7 @@ def __get_supervisor(self): def _check_path_length(self): sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - bind_path = self.supervisord_conf_path + bind_path = self.supervisord_sock_path try: sock.bind(bind_path) except OSError as e: From 29562cb1cbd91cae9a48b5d4d16250b32ac26421 Mon Sep 17 00:00:00 2001 From: Sergey Golitsynskiy Date: Tue, 14 Jun 2022 16:44:24 -0400 Subject: [PATCH 4/6] Silence error --- gravity/process_manager/supervisor_manager.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gravity/process_manager/supervisor_manager.py b/gravity/process_manager/supervisor_manager.py index c218fd2..efd79da 100644 --- a/gravity/process_manager/supervisor_manager.py +++ b/gravity/process_manager/supervisor_manager.py @@ -228,7 +228,7 @@ def __supervisord(self): if not self.__supervisord_is_running(): # any time that supervisord is not running, let's rewrite supervisord.conf open(self.supervisord_conf_path, "w").write(SUPERVISORD_CONF_TEMPLATE.format(**format_vars)) - self.__supervisord_popen = subprocess.Popen(supervisord_cmd, env=os.environ, stderr=subprocess.PIPE) + self.__supervisord_popen = subprocess.Popen(supervisord_cmd, env=os.environ) rc = self.__supervisord_popen.poll() if rc: @@ -257,7 +257,10 @@ def _check_path_length(self): self._handle_socket_path_error() finally: sock.close() - os.unlink(bind_path) + try: + os.unlink(bind_path) + except FileNotFoundError: + pass # There's nothing to unlink. File may not exists during testing. def _handle_socket_path_error(self): msg = f""" From d0247ae1113feb3f545b51d9d6e219cb6f4ec3ac Mon Sep 17 00:00:00 2001 From: Sergey Golitsynskiy Date: Tue, 14 Jun 2022 16:52:35 -0400 Subject: [PATCH 5/6] Don't check the path before creating the dir --- gravity/process_manager/supervisor_manager.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/gravity/process_manager/supervisor_manager.py b/gravity/process_manager/supervisor_manager.py index efd79da..fb53dcb 100644 --- a/gravity/process_manager/supervisor_manager.py +++ b/gravity/process_manager/supervisor_manager.py @@ -195,11 +195,11 @@ def __init__(self, state_dir=None, start_daemon=True, foreground=False): self.__supervisord_popen = None self.foreground = foreground - self._check_path_length() - if not exists(self.supervisord_conf_dir): os.makedirs(self.supervisord_conf_dir) + self._check_path_length() + if start_daemon: self.__supervisord() @@ -255,12 +255,11 @@ def _check_path_length(self): except OSError as e: if "AF_UNIX path too long" in str(e): self._handle_socket_path_error() + else: + raise e finally: sock.close() - try: - os.unlink(bind_path) - except FileNotFoundError: - pass # There's nothing to unlink. File may not exists during testing. + os.unlink(bind_path) def _handle_socket_path_error(self): msg = f""" From cee936133dc0e2a341b13e12f4c4eb3007ff51e6 Mon Sep 17 00:00:00 2001 From: Sergey Golitsynskiy Date: Tue, 14 Jun 2022 17:01:40 -0400 Subject: [PATCH 6/6] Unlink before binding --- gravity/process_manager/supervisor_manager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/gravity/process_manager/supervisor_manager.py b/gravity/process_manager/supervisor_manager.py index fb53dcb..3575097 100644 --- a/gravity/process_manager/supervisor_manager.py +++ b/gravity/process_manager/supervisor_manager.py @@ -251,6 +251,7 @@ def _check_path_length(self): sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) bind_path = self.supervisord_sock_path try: + os.unlink(bind_path) sock.bind(bind_path) except OSError as e: if "AF_UNIX path too long" in str(e):