From d60bccb82cd49c4bfee98fc69c5661980b3809b2 Mon Sep 17 00:00:00 2001 From: Victor Allombert Date: Thu, 31 Jul 2025 09:17:05 +0200 Subject: [PATCH 1/4] Tezt/Cloud/Service_manager: minor refacto --- tezt/lib_cloud/service_manager.ml | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/tezt/lib_cloud/service_manager.ml b/tezt/lib_cloud/service_manager.ml index 7730e5175f27..991d9bbbed69 100644 --- a/tezt/lib_cloud/service_manager.ml +++ b/tezt/lib_cloud/service_manager.ml @@ -99,19 +99,15 @@ let register_service ~name ~executable let () = if Hashtbl.length t.services = 0 then start t else () in (* Get the real executable name *) (* Note: this only works on remote vm *) - if Sys.file_exists executable then - let executable = Unix.realpath executable in - let service = - {executable = Some executable; on_alive_callback; pid = None; on_shutdown} + let service = + let executable = + if Sys.file_exists executable then Some (Unix.realpath executable) + else None in - let () = Hashtbl.add t.services name service in - Log.info "%s: Registering service: %s (%s)" section name executable - else - let service = - {executable = None; on_alive_callback; pid = None; on_shutdown} - in - let () = Hashtbl.add t.services name service in - Log.info "%s: Registering service: %s (%s)" section name executable + {executable; on_alive_callback; pid = None; on_shutdown} + in + let () = Hashtbl.add t.services name service in + Log.info "%s: Registering service: %s (%s)" section name executable let notify_start_service ~name ~pid t = match Hashtbl.find_opt t.services name with -- GitLab From 7f42d7f0fdf7a701beb8ec7a1594849a2387e0e4 Mon Sep 17 00:00:00 2001 From: Victor Allombert Date: Thu, 31 Jul 2025 09:28:48 +0200 Subject: [PATCH 2/4] Tezt/Cloud: introduce and use ssh option placeholder --- tezt/lib_cloud/agent.ml | 4 ++-- tezt/lib_cloud/ssh.ml | 4 ++++ tezt/lib_cloud/ssh.mli | 5 ++++- tezt/lib_cloud/tezt_cloud.ml | 1 + tezt/lib_cloud/tezt_cloud.mli | 1 + 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/tezt/lib_cloud/agent.ml b/tezt/lib_cloud/agent.ml index c7e73af1042f..be38a266c559 100644 --- a/tezt/lib_cloud/agent.ml +++ b/tezt/lib_cloud/agent.ml @@ -128,7 +128,7 @@ let encoding = I don't have a good proposition that keeps a nice UX and is secure at the moment. *) Runner.create - ~options:["-o"; "StrictHostKeyChecking=no"] + ~options:Ssh.ssh_options ~ssh_user:"root" ~ssh_id ~ssh_port @@ -184,7 +184,7 @@ let make ?zone ?ssh_id ?point ~configuration ~next_available_port ~vm_name Test.fail "Agent.make was not initialized correctly" | Some (address, ssh_port), Some ssh_id -> Runner.create - ~options:["-o"; "StrictHostKeyChecking=no"] + ~options:Ssh.ssh_options ~ssh_user ~ssh_id ~ssh_port diff --git a/tezt/lib_cloud/ssh.ml b/tezt/lib_cloud/ssh.ml index bee0fabcc783..77f64aaa07cc 100644 --- a/tezt/lib_cloud/ssh.ml +++ b/tezt/lib_cloud/ssh.ml @@ -24,3 +24,7 @@ let public_key () = Process.run_and_read_stdout ~name:"cat" "cat" [ssh_public_key_filename] in Lwt.return content + +let common_options = ["-o"; "StrictHostKeyChecking=no"] + +let ssh_options = common_options diff --git a/tezt/lib_cloud/ssh.mli b/tezt/lib_cloud/ssh.mli index 594ceedc1146..d72a1c31ec9c 100644 --- a/tezt/lib_cloud/ssh.mli +++ b/tezt/lib_cloud/ssh.mli @@ -1,7 +1,7 @@ (*****************************************************************************) (* *) (* SPDX-License-Identifier: MIT *) -(* SPDX-FileCopyrightText: 2024 Nomadic Labs *) +(* SPDX-FileCopyrightText: 2025 Nomadic Labs *) (* *) (*****************************************************************************) @@ -12,3 +12,6 @@ val generate_key : unit -> unit Lwt.t (** [ssh_public_key()] returns the ssh public key associated to the generate_key It calls [generate_key] if it does not exist *) val public_key : unit -> string Lwt.t + +(* Default options required to properly run through ssh. *) +val ssh_options : string list diff --git a/tezt/lib_cloud/tezt_cloud.ml b/tezt/lib_cloud/tezt_cloud.ml index 9e693ad953f8..b53d44aca456 100644 --- a/tezt/lib_cloud/tezt_cloud.ml +++ b/tezt/lib_cloud/tezt_cloud.ml @@ -9,6 +9,7 @@ module Path = Path module Agent = Agent module Types = Types module Chronos = Chronos +module Ssh = Ssh module Alert = struct include Alert_manager diff --git a/tezt/lib_cloud/tezt_cloud.mli b/tezt/lib_cloud/tezt_cloud.mli index 4c463fd37f2e..0a24c8e52b67 100644 --- a/tezt/lib_cloud/tezt_cloud.mli +++ b/tezt/lib_cloud/tezt_cloud.mli @@ -8,6 +8,7 @@ module Path = Path module Agent = Agent module Types = Types +module Ssh = Ssh module Chronos : sig (** A scheduler task. *) -- GitLab From 38f4d87bc7f5a22f6fc848bf80343a5e09042f18 Mon Sep 17 00:00:00 2001 From: Victor Allombert Date: Thu, 31 Jul 2025 09:34:32 +0200 Subject: [PATCH 3/4] Tezt/Cloud: introduce and use scp option placeholder --- tezt/lib_cloud/agent.ml | 5 +---- tezt/lib_cloud/ssh.ml | 11 +++++++++++ tezt/lib_cloud/ssh.mli | 5 +++++ tezt/tests/cloud/agent_kind.ml | 4 +--- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/tezt/lib_cloud/agent.ml b/tezt/lib_cloud/agent.ml index be38a266c559..e58a8323d81d 100644 --- a/tezt/lib_cloud/agent.ml +++ b/tezt/lib_cloud/agent.ml @@ -337,13 +337,10 @@ let copy agent ~consistency_check ~is_directory ~source ~destination = runner.Runner.ssh_port in let* () = - (* FIXME: I forgot why we enforce [-0]. *) Process.run "scp" ((if is_directory then ["-r"] else []) - @ ["-O"] - @ ["-o"; "StrictHostKeyChecking=no"] - @ identity @ port @ [source] @ [destination]) + @ Ssh.scp_options @ identity @ port @ [source] @ [destination]) in Lwt.return_unit diff --git a/tezt/lib_cloud/ssh.ml b/tezt/lib_cloud/ssh.ml index 77f64aaa07cc..79b0e4030f22 100644 --- a/tezt/lib_cloud/ssh.ml +++ b/tezt/lib_cloud/ssh.ml @@ -28,3 +28,14 @@ let public_key () = let common_options = ["-o"; "StrictHostKeyChecking=no"] let ssh_options = common_options + +(* Default options required to properly run scp command. As scp command's syntax + is close to the ssh one, we reuse the [ssh_options]. This might be breaking + if incompatible ssh options are used. + + The [-O] option forces the use of the SCP protocol, instead of the SFTP + protocol. This may be necessary for servers that do not implement SFTP, for + backwards-compatibility for particular filename wildcard patterns and for + expanding paths with a ‘~’ prefix for older SFTP servers. +*) +let scp_options = ["-O"] @ common_options diff --git a/tezt/lib_cloud/ssh.mli b/tezt/lib_cloud/ssh.mli index d72a1c31ec9c..9cee09a88cfc 100644 --- a/tezt/lib_cloud/ssh.mli +++ b/tezt/lib_cloud/ssh.mli @@ -15,3 +15,8 @@ val public_key : unit -> string Lwt.t (* Default options required to properly run through ssh. *) val ssh_options : string list + +(* Default options required to properly run scp command. As scp command's syntax + is close to the ssh one, we reuse the [ssh_options]. This might be breaking + if incompatible ssh options are used. *) +val scp_options : string list diff --git a/tezt/tests/cloud/agent_kind.ml b/tezt/tests/cloud/agent_kind.ml index 9cc6ab224c6d..775712990410 100644 --- a/tezt/tests/cloud/agent_kind.ml +++ b/tezt/tests/cloud/agent_kind.ml @@ -107,9 +107,7 @@ module Logs = struct (fun () -> Process.run "scp" - (["-r"] @ ["-O"] - @ ["-o"; "StrictHostKeyChecking=no"] - @ identity @ port + (Ssh.scp_options @ ["-r"] @ identity @ port @ [source // daemon_name // "daily_logs"] @ [local_path // "daily_logs"])) (fun exn -> -- GitLab From 39192d1ec84a89f710c63c9d4c6b8c4f69d42033 Mon Sep 17 00:00:00 2001 From: Victor Allombert Date: Thu, 31 Jul 2025 09:42:57 +0200 Subject: [PATCH 4/4] Tezt/Cloud: use runner.options for ssh config --- tezt/lib_cloud/cloud.ml | 11 ++++------- tezt/lib_cloud/web.ml | 19 +++++++++---------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/tezt/lib_cloud/cloud.ml b/tezt/lib_cloud/cloud.ml index c177d59679ff..676a5fdebdb1 100644 --- a/tezt/lib_cloud/cloud.ml +++ b/tezt/lib_cloud/cloud.ml @@ -160,7 +160,7 @@ let wait_ssh_server_running agent = runner (Runner.Shell.cmd [] "echo" ["-n"; "check"]) in - Process.spawn cmd (["-o"; "StrictHostKeyChecking=no"] @ args) + Process.spawn cmd (runner.options @ args) in let* _ = Env.wait_process ~is_ready ~run () in Lwt.return_unit @@ -330,8 +330,7 @@ let attach agent = (Runner.Shell.cmd [] "screen" ["-S"; "tezt-cloud"; "-X"; "stuff"; "^C"]) in let* () = - Process.spawn ~hooks cmd (["-o"; "StrictHostKeyChecking=no"] @ args) - |> Process.check + Process.spawn ~hooks cmd (runner.options @ args) |> Process.check in let cmd, args = Runner.wrap_with_ssh @@ -339,8 +338,7 @@ let attach agent = (Runner.Shell.cmd [] "stdbuf" ["-oL"; "tail"; "-F"; "screenlog.0"]) in let _p = - Process.spawn ~hooks cmd (["-o"; "StrictHostKeyChecking=no"] @ args) - |> Process.check + Process.spawn ~hooks cmd (runner.options @ args) |> Process.check in let* _ = Input.eof in let* () = @@ -390,8 +388,7 @@ let attach agent = Lwt.catch (fun () -> let* () = - Process.spawn ~hooks cmd (["-o"; "StrictHostKeyChecking=no"] @ args) - |> Process.check + Process.spawn ~hooks cmd (runner.options @ args) |> Process.check in Lwt.return_unit) (fun exn -> diff --git a/tezt/lib_cloud/web.ml b/tezt/lib_cloud/web.ml index 8591c0e203ae..600263e8279f 100644 --- a/tezt/lib_cloud/web.ml +++ b/tezt/lib_cloud/web.ml @@ -39,16 +39,15 @@ let string_docker_command agent = let ssh_id = runner.Runner.ssh_id in String.concat " " - [ - "ssh"; - Format.asprintf "root@%s" (fst point); - "-p"; - string_of_int (snd point); - "-o"; - "StrictHostKeyChecking=no"; - "-i"; - ssh_id |> Option.get; - ] + ([ + "ssh"; + Format.asprintf "root@%s" (fst point); + "-p"; + string_of_int (snd point); + "-i"; + ssh_id |> Option.get; + ] + @ runner.options) let string_vm_command agent = match Agent.cmd_wrapper agent with -- GitLab