From 93e4787b70a85cc5f13db5e55ef0c06629b45e6e Mon Sep 17 00:00:00 2001 From: Xiaodong DENG Date: Tue, 22 Dec 2020 23:18:38 +0100 Subject: [PATCH] Allow PID file path to be relative when daemonize a process (scheduler, kerberos, etc) (#13232) Closes #13200. Currently, if the PID file path provided is relative, the process silently fails to launch. This fix ensures the PID path specified to be a normalized absolutized path eventually (expand with cwd), no matter the given value is relative or absolute. --- airflow/utils/cli.py | 3 +++ tests/utils/test_cli_util.py | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/airflow/utils/cli.py b/airflow/utils/cli.py index 7cd8946be3b3a..68a0b448d7868 100644 --- a/airflow/utils/cli.py +++ b/airflow/utils/cli.py @@ -227,8 +227,11 @@ def setup_locations(process, pid=None, stdout=None, stderr=None, log=None): stdout = os.path.join(settings.AIRFLOW_HOME, f'airflow-{process}.out') if not log: log = os.path.join(settings.AIRFLOW_HOME, f'airflow-{process}.log') + if not pid: pid = os.path.join(settings.AIRFLOW_HOME, f'airflow-{process}.pid') + else: + pid = os.path.abspath(pid) return pid, stdout, stderr, log diff --git a/tests/utils/test_cli_util.py b/tests/utils/test_cli_util.py index 64cd57fd16775..5a64c457b9837 100644 --- a/tests/utils/test_cli_util.py +++ b/tests/utils/test_cli_util.py @@ -131,6 +131,23 @@ def test_cli_create_user_supplied_password_is_masked(self, given_command, expect command = json.loads(command.replace("'", '"')) self.assertEqual(command, expected_command) + def test_setup_locations_relative_pid_path(self): + relative_pid_path = "fake.pid" + pid_full_path = os.path.join(os.getcwd(), relative_pid_path) + pid, _, _, _ = cli.setup_locations(process="fake_process", pid=relative_pid_path) + self.assertEqual(pid, pid_full_path) + + def test_setup_locations_absolute_pid_path(self): + abs_pid_path = os.path.join(os.getcwd(), "fake.pid") + pid, _, _, _ = cli.setup_locations(process="fake_process", pid=abs_pid_path) + self.assertEqual(pid, abs_pid_path) + + def test_setup_locations_none_pid_path(self): + process_name = "fake_process" + default_pid_path = os.path.join(settings.AIRFLOW_HOME, f"airflow-{process_name}.pid") + pid, _, _, _ = cli.setup_locations(process=process_name) + self.assertEqual(pid, default_pid_path) + @contextmanager def fail_action_logger_callback():