let put_file ?timeout t ~path ~content =
  match connection t with
  | `Localhost -> IO.write_file ~content Path.(to_string path)
  | `Ssh ssh ->
    let temp = Filename.temp_file "ketrew" "ssh_put_file" in
    let run ~log () =
      IO.write_file ~content temp
      >>= fun () ->
      let scp_cmd = Ssh.(scp_push ssh ~src:[temp] ~dest:(Path.to_string path)) in
      begin Ketrew_unix_process.succeed scp_cmd
        >>< function
        | `Ok (out, err) -> return ()
        | `Error (`Process _ as process_error) ->
          let msg = Ketrew_unix_process.error_to_string process_error in
          Log.(s "Scp-cmd " % OCaml.list (sf "%S") scp_cmd  % sp % log
               % s " failed: " %s msg @ verbose);
          fail_exec t msg
      end
    in
    begin run_with_timeout ?timeout t ~run
      >>< function
      | `Ok o -> return o
      | `Error (`IO _ as e) -> fail e
      | `Error (`Host e) -> fail (`Host e)
      | `Error (`System _ as e)
      | `Error (`Timeout _ as e) -> fail (`Host e)
    end