Skip to content

Instantly share code, notes, and snippets.

@rodrigues
Last active January 28, 2019 22:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rodrigues/da15b1e701f25b86c9dba1775955da91 to your computer and use it in GitHub Desktop.
Save rodrigues/da15b1e701f25b86c9dba1775955da91 to your computer and use it in GitHub Desktop.
`RemShell.print_instructions("myhost.com")`
defmodule RemShell do
import IO.ANSI, only: [underline: 0, bright: 0, reset: 0]
@moduledoc """
Outputs commands to run a remote shell
from your machine to a remote host.
"""
# TODO replace with real values
@app :kebab
@cookie :kebab
def print_instructions(host) do
IO.puts("""
#{explanation("ssh port forwarding")}
#{command(port_forwarding(host))}
#{explanation("remote shell")}
#{command(remote_shell())}
#{explanation("observer")}
#{command(observer())}
> Node.connect :"#{@app}@127.0.0.1"
> :observer.start
# Change Node in GUI
""")
end
defp explanation(message) do
"#{underline()}# #{message}#{reset()}\n"
end
defp command(parts) do
"$ #{bright()} #{parts |> Enum.join(" ")}#{reset()}"
end
defp port_forwarding(host) do
{epmd_port, app_port} = host |> fetch_ports()
[
"ssh #{@app}@#{host}",
"-L#{epmd_port}:localhost:#{epmd_port}",
"-L#{app_port}:localhost:#{app_port}"
]
end
defp remote_shell do
[
"iex --name #{whoami()}@127.0.0.1",
"--cookie #{@cookie}",
"--remsh #{@app}@127.0.0.1"
]
end
defp observer do
[
"iex --name #{whoami()}@127.0.0.1",
"--cookie #{@cookie}"
]
end
defp whoami do
'whoami' |> :os.cmd() |> to_string |> String.trim()
end
defp fetch_ports(host) do
erts_finder_cmd = 'ssh #{@app}@#{host} "ps ax | grep epmd | grep erts"'
epmd_path =
erts_finder_cmd
|> :os.cmd()
|> to_string
|> String.split(" ", trim: true)
|> Enum.find(&String.ends_with?(&1, "/epmd"))
epmd_port_cmd = 'ssh #{@app}@#{host} "#{epmd_path} -names"'
lines =
epmd_port_cmd
|> :os.cmd()
|> to_string
|> String.split("\n")
epmd = lines |> Enum.at(0) |> epmd_port
app = lines |> Enum.find_value(&app_port/1)
{epmd, app}
end
defp epmd_port(line) do
[[_, port]] = ~r/port\s(\d+)/ |> Regex.scan(line)
port
end
@app_prefix "name #{@app} at port "
defp app_port(@app_prefix <> port), do: port
defp app_port(_), do: nil
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment