diff --git a/tezt/lib_cloud/agent.ml b/tezt/lib_cloud/agent.ml index 8561deb21565bedbfcc3fea031f5c3c0dbe3360d..86c0b9fece4fd11cd03c9e34baa1b8a627265907 100644 --- a/tezt/lib_cloud/agent.ml +++ b/tezt/lib_cloud/agent.ml @@ -17,11 +17,12 @@ module Configuration = struct let uri_of_docker_image docker_image = match (docker_image, Env.mode) with - | Types.Agent_configuration.Gcp {alias}, (`Cloud | `Host | `Orchestrator) -> + | ( Types.Agent_configuration.Gcp {alias}, + (`Cloud | `Host | `Orchestrator | `Ssh_host _) ) -> let* registry_uri = Env.registry_uri () in Lwt.return (Format.asprintf "%s/%s" registry_uri alias) | Gcp {alias}, `Localhost -> Lwt.return alias - | Octez_release _, (`Cloud | `Host | `Orchestrator) -> + | Octez_release _, (`Cloud | `Host | `Orchestrator | `Ssh_host _) -> let* registry_uri = Env.registry_uri () in Lwt.return (Format.asprintf "%s/octez" registry_uri) | Octez_release _, `Localhost -> Lwt.return "octez" diff --git a/tezt/lib_cloud/cli.ml b/tezt/lib_cloud/cli.ml index cac2031b1d77b12a1674b3c25a0c7852c2892f94..cafc432a8e12e9a122b4724f17aa951a38fbccf3 100644 --- a/tezt/lib_cloud/cli.ml +++ b/tezt/lib_cloud/cli.ml @@ -22,6 +22,13 @@ let localhost = ~description:"If set, the test is run locally" false +let ssh_host = + Clap.optional_string + ~section + ~long:"ssh-host" + ~description:"Whether to provision a non-gcp vm host via ssh" + () + let monitoring = Clap.flag ~section diff --git a/tezt/lib_cloud/cli.mli b/tezt/lib_cloud/cli.mli index cf80d28babd10b082c441863700a9148e51905f6..bd119f3207665756dc1a030706bbb64b3d82b5cc 100644 --- a/tezt/lib_cloud/cli.mli +++ b/tezt/lib_cloud/cli.mli @@ -143,3 +143,6 @@ val binaries_path : string Defaults to 300 Use 0 to disable log-rotation *) val log_rotation : int + +(** The hostname of the host accessed by ssh on which to deploy *) +val ssh_host : string option diff --git a/tezt/lib_cloud/cloud.ml b/tezt/lib_cloud/cloud.ml index bc3c979d24be72e1b38decad0b2ceb26b187911b..5efc413a40f963ee523429ddcfd9a8dca902512c 100644 --- a/tezt/lib_cloud/cloud.ml +++ b/tezt/lib_cloud/cloud.ml @@ -470,7 +470,17 @@ let init_proxy ?(proxy_files = []) ?(proxy_args = []) deployement = in let process = let args = + (* remove "--ssh-host host" from the commande line *) + let rec filter_ssh acc args = + match args with + | [] -> List.rev acc + (* FIXME: remove proxy-localhost when agent name bug is fixed *) + | "--ssh-host" :: _host :: args -> + filter_ssh ("--proxy-localhost" :: "--proxy" :: acc) args + | arg :: args -> filter_ssh (arg :: acc) args + in let args = Sys.argv |> Array.to_list |> List.tl in + let args = filter_ssh [] args in args @ ["--localhost"; "--tezt-cloud"; Env.tezt_cloud] (* [--localhost] will be combined with --proxy, this enables to detect we want to run in [`Orchestrator]. @@ -552,7 +562,7 @@ let register ?proxy_files ?proxy_args ?vms ~__FILE__ ~title ~tags ?seed ?alerts future." ; match Env.mode with | `Localhost | `Cloud -> None - | `Host | `Orchestrator -> + | `Host | `Orchestrator | `Ssh_host (_, _) -> (* In Host mode, we want to run a deployment deploying the Proxy VM. In orchestrator mode, there is few initialisation steps needed. By using [Some []], we @@ -664,7 +674,7 @@ let register ?proxy_files ?proxy_args ?vms ~__FILE__ ~title ~tags ?seed ?alerts let* deployement = Deployement.deploy ~configurations in let* () = ensure_ready deployement in orchestrator ?alerts ?tasks deployement f - | `Host -> + | `Host | `Ssh_host _ -> (* The scenario is executed remotely. *) let* proxy_running = try_reattach () in if not proxy_running then @@ -709,7 +719,7 @@ let agents t = in [default_agent] | agents -> agents) - | `Host | `Cloud | `Localhost -> t.agents + | `Host | `Cloud | `Localhost | `Ssh_host _ -> t.agents let write_website t = match t.website with diff --git a/tezt/lib_cloud/deployement.ml b/tezt/lib_cloud/deployement.ml index 393d008758d3e2c0f3ef592552ba84ca83585154..0ef9614317b9ca6433ea5688ef3fba3fbd0207f4 100644 --- a/tezt/lib_cloud/deployement.ml +++ b/tezt/lib_cloud/deployement.ml @@ -187,7 +187,7 @@ module Remote = struct let () = Log.report ~color:Log.Color.FG.green - "DNS registrered successfully: '%s'" + "DNS registered successfully: '%s'" domain in Lwt.return_unit @@ -355,8 +355,8 @@ module Ssh_host = struct in Lwt.return agent - let _deploy ~user ~host ~port ~(configurations : Agent.Configuration.t list) - () = + let deploy ~user ~host ~port ~(configurations : Agent.Configuration.t list) () + = let proxy_runner = Runner.create ~ssh_user:"root" ~ssh_port:port ~address:host () in @@ -428,9 +428,9 @@ module Ssh_host = struct let agents = proxy :: agents in Lwt.return {point = (user, host, port); agents} - let _agents t = t.agents + let agents t = t.agents - let _terminate {point; agents} = + let terminate {point; agents} = let _user, host, port = point in let* () = Lwt_list.iter_p @@ -596,7 +596,10 @@ module Localhost = struct else Lwt.return_unit end -type t = Remote of Remote.t | Localhost of Localhost.t +type t = + | Remote of Remote.t + | Ssh_host of Ssh_host.t + | Localhost of Localhost.t let deploy ~configurations = match Env.mode with @@ -610,15 +613,22 @@ let deploy ~configurations = let* remote = Remote.deploy ~proxy:true ~configurations in Lwt.return (Remote remote) | `Orchestrator -> assert false + | `Ssh_host (host, port) -> + let* host = + Ssh_host.deploy ~user:(Sys.getenv "USER") ~host ~port ~configurations () + in + Lwt.return (Ssh_host host) let agents t = match t with | Remote remote -> Remote.agents remote | Localhost localhost -> Localhost.agents localhost + | Ssh_host remote -> Ssh_host.agents remote let terminate ?exn t = match t with | Remote remote -> Remote.terminate ?exn remote | Localhost localhost -> Localhost.terminate ?exn localhost + | Ssh_host remote -> Ssh_host.terminate remote let of_agents agents = Remote {agents} diff --git a/tezt/lib_cloud/env.ml b/tezt/lib_cloud/env.ml index 908e6f5815e0b15c2ae72319421f4d2b812d6adf..2f9f4a4f1346e38a6eaf25f5297770cb57a2d4a4 100644 --- a/tezt/lib_cloud/env.ml +++ b/tezt/lib_cloud/env.ml @@ -12,6 +12,25 @@ let tezt_cloud = (* This is a lazy value to be sure that this is evaluated only inside a Tezt test. *) match Sys.getenv_opt "TEZT_CLOUD" with None -> "" | Some value -> value) +let mode = + match (Cli.localhost, Cli.proxy, Cli.ssh_host) with + | true, true, None -> `Orchestrator + | true, false, None -> `Localhost + | false, true, None -> `Host + | false, false, None -> `Cloud + | true, _, Some _ | _, true, Some _ -> + Test.fail + "Unexpected combination of options: ssh_host and (proxy or localhost)" + | _, _, Some endpoint -> + let uri = Uri.of_string (Format.asprintf "tcp://%s" endpoint) in + let host = + match Uri.host uri with + | None -> Test.fail "No valid hostname specified: %s" endpoint + | Some host -> host + in + let port = Option.value ~default:22 (Uri.port uri) in + `Ssh_host (host, port) + let ssh_private_key_filename ?(home = Sys.getenv "HOME") () = home // ".ssh" // Format.asprintf "%s-tf" tezt_cloud @@ -19,13 +38,6 @@ let ssh_public_key_filename ?home () = let ssh_key = ssh_private_key_filename ?home () in Format.asprintf "%s.pub" ssh_key -let mode = - match (Cli.localhost, Cli.proxy) with - | true, true -> `Orchestrator - | true, false -> `Localhost - | false, true -> `Host - | false, false -> `Cloud - let prometheus = Cli.prometheus let prometheus_export = Cli.prometheus_export @@ -133,6 +145,7 @@ let init () = ( with_open_out pidfile @@ fun fd -> output_string fd (Format.asprintf "%d\n" pid) ) ; Lwt.return_unit + | `Ssh_host _ -> Lwt.return_unit | `Host | `Cloud -> let* project_id = project_id () in Log.info "Initializing docker registry..." ; @@ -222,7 +235,8 @@ let dns_domains () = match domain with | None -> Lwt.return Cli.dns_domains | Some domain -> Lwt.return (domain :: Cli.dns_domains)) - | `Orchestrator | `Localhost | `Cloud -> Lwt.return Cli.dns_domains + | `Orchestrator | `Localhost | `Cloud | `Ssh_host _ -> + Lwt.return Cli.dns_domains in (* A fully-qualified domain name requires to end with a dot. However, the usage tends to omit this final dot. Because having a diff --git a/tezt/lib_cloud/env.mli b/tezt/lib_cloud/env.mli index a507c48fe41c2cc0d636569a823cb084e9fea250..d5376d67e5753591318d2c35455e18f2b45586bf 100644 --- a/tezt/lib_cloud/env.mli +++ b/tezt/lib_cloud/env.mli @@ -31,8 +31,13 @@ val ssh_public_key_filename : ?home:string -> unit -> string - [`Host]: This mode is run by the host machine that initializes the orchestrator running on a VM. + + - [`Ssh_host (host, port)]: This mode is similar to the Orchestrator mode, but + on a non-gcp vm. Its purpose is to make an initial provisioning + of docker if it is not setup. *) -val mode : [`Localhost | `Cloud | `Orchestrator | `Host] +val mode : + [`Localhost | `Ssh_host of string * int | `Cloud | `Orchestrator | `Host] (** Equivalent to [Cli.prometheus]. *) val prometheus : bool diff --git a/tezt/lib_cloud/web.ml b/tezt/lib_cloud/web.ml index 5a830cb7bed7726545f73e82e82792fb966d9e83..a4fd374461822893ae417c607e410e19b625213b 100644 --- a/tezt/lib_cloud/web.ml +++ b/tezt/lib_cloud/web.ml @@ -24,7 +24,8 @@ let pp_docker_image fmt = function let domain agents = match Env.mode with - | `Orchestrator -> Proxy.get_agent agents |> Agent.point |> Option.get |> fst + | `Orchestrator | `Ssh_host _ -> + Proxy.get_agent agents |> Agent.point |> Option.get |> fst | `Host | `Localhost | `Cloud -> "localhost" let string_docker_command agent =