diff --git a/src/pobsync_backend/preflight.py b/src/pobsync_backend/preflight.py index cd432cf..6fbb9db 100644 --- a/src/pobsync_backend/preflight.py +++ b/src/pobsync_backend/preflight.py @@ -97,9 +97,7 @@ def run_remote_preflight(host: HostConfig, *, timeout_seconds: int = 20) -> dict *ssh_cmd, "-oBatchMode=yes", target, - "sh", - "-lc", - f"command -v {shlex.quote(rsync_binary)} >/dev/null", + _remote_shell_command(f"command -v {shlex.quote(rsync_binary)} >/dev/null"), ], timeout_seconds=timeout_seconds, ), @@ -109,9 +107,7 @@ def run_remote_preflight(host: HostConfig, *, timeout_seconds: int = 20) -> dict *ssh_cmd, "-oBatchMode=yes", target, - "sh", - "-lc", - f"test -e {shlex.quote(source_root)} && test -r {shlex.quote(source_root)}", + _remote_shell_command(f"test -e {shlex.quote(source_root)} && test -r {shlex.quote(source_root)}"), ], timeout_seconds=timeout_seconds, ), @@ -129,6 +125,10 @@ def run_remote_preflight(host: HostConfig, *, timeout_seconds: int = 20) -> dict return result +def _remote_shell_command(script: str) -> str: + return f"sh -lc {shlex.quote(script)}" + + def effective_host_config_preview(host: HostConfig, global_config: GlobalConfig) -> dict[str, Any]: config = build_effective_config(global_config_object_data(global_config), host_config_object_data(host)) credential = host.ssh_credential or global_config.default_ssh_credential diff --git a/src/pobsync_backend/tests/test_views.py b/src/pobsync_backend/tests/test_views.py index 951fec8..ceac279 100644 --- a/src/pobsync_backend/tests/test_views.py +++ b/src/pobsync_backend/tests/test_views.py @@ -1100,6 +1100,10 @@ class ViewTests(TestCase): self.assertContains(response, "Remote rsync") self.assertContains(response, "Remote source root") self.assertEqual(run.call_count, 3) + commands = [call.kwargs["args"] if "args" in call.kwargs else call.args[0] for call in run.call_args_list] + self.assertEqual(commands[1][-1], "sh -lc 'command -v rsync >/dev/null'") + self.assertEqual(commands[2][-1], "sh -lc 'test -e / && test -r /'") + self.assertNotIn("sh", commands[2][commands[2].index("root@web-01.example.test") + 1 : -1]) host.refresh_from_db() self.assertTrue(host.config["last_preflight"]["ok"]) self.assertEqual(host.config["last_preflight"]["target"], "root@web-01.example.test")