Skip to content

Commit ebe3e2b

Browse files
committed
Support custom node name ids to allow multiple remote connections. Fixes #623
1 parent 19f4169 commit ebe3e2b

File tree

1 file changed

+40
-7
lines changed

1 file changed

+40
-7
lines changed

lib/mix/lib/releases/runtime/control.ex

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,19 @@ defmodule Mix.Releases.Runtime.Control do
2626
transform: &String.to_atom/1
2727
)
2828

29+
defoption(
30+
:id,
31+
:string,
32+
"The unique id to use when connecting to the remote node"
33+
)
34+
2935
option(:verbose, :boolean, "Turns on verbose output", alias: :v)
3036

3137
# Basic management tasks
3238
command :ping, "Pings the remote node" do
3339
option(:cookie, required: true)
3440
option(:name)
41+
option(:id)
3542
end
3643

3744
# Stub for `describe`
@@ -40,16 +47,19 @@ defmodule Mix.Releases.Runtime.Control do
4047
command :stop, "Stops the remote node" do
4148
option(:name)
4249
option(:cookie)
50+
option(:id)
4351
end
4452

4553
command :restart, "Restarts the remote node. This will not restart the emulator" do
4654
option(:name)
4755
option(:cookie)
56+
option(:id)
4857
end
4958

5059
command :reboot, "Reboots the remote node. This will restart the emulator" do
5160
option(:name)
5261
option(:cookie)
62+
option(:id)
5363
end
5464

5565
# Stub for `describe`
@@ -65,6 +75,7 @@ defmodule Mix.Releases.Runtime.Control do
6575
command :unpack, "Unpacks a release upgrade for installation" do
6676
option(:name)
6777
option(:cookie)
78+
option(:id)
6879
option(:release, :string, "The release name", required: true, hidden: true)
6980

7081
argument(:version, :string, "The release version to unpack", required: true)
@@ -73,6 +84,7 @@ defmodule Mix.Releases.Runtime.Control do
7384
command :install, "Installs a release upgrade" do
7485
option(:name)
7586
option(:cookie)
87+
option(:id)
7688
option(:release, :string, "The release name", required: true, hidden: true)
7789

7890
argument(:version, :string, "The release version to install", required: true)
@@ -82,12 +94,14 @@ defmodule Mix.Releases.Runtime.Control do
8294
command :reload_config, "Reloads the config of the remote node" do
8395
option(:name)
8496
option(:cookie)
97+
option(:id)
8598
option(:sysconfig, :string, "The path to a sys.config file")
8699
end
87100

88101
command :rpc, "Executes the provided expression on the remote node" do
89102
option(:name)
90103
option(:cookie)
104+
option(:id)
91105
option(:file, :string, "Evaluate a file instead of an expression")
92106
option(:mfa, :string, "A module/function/arity string, e.g. IO.inspect/1")
93107

@@ -120,6 +134,7 @@ defmodule Mix.Releases.Runtime.Control do
120134
command :info, "Prints information about the remote node to stdout" do
121135
option(:name)
122136
option(:cookie)
137+
option(:id)
123138

124139
command :processes, [callback: :processes_info], "Show a table of running processes" do
125140
option(
@@ -135,6 +150,7 @@ defmodule Mix.Releases.Runtime.Control do
135150
command :describe, "Describes the currently installed release" do
136151
option(:name)
137152
option(:cookie)
153+
option(:id)
138154
option(:release, :string, "The name of the release")
139155
option(:release_root_dir, :string, "The root directory for all releases")
140156
option(:sysconfig, :string, "The path to the sys.config file used by the release")
@@ -147,9 +163,17 @@ defmodule Mix.Releases.Runtime.Control do
147163
This function executes before any commands are dispatched
148164
"""
149165
@impl Artificery
150-
def pre_dispatch(_cmd, _argv, %{name: name, cookie: cookie} = opts) do
151-
# If required, it means we need to connect to the remote node
152-
{:ok, peer, name, type} = start_distribution!(name, cookie)
166+
def pre_dispatch(_cmd, _argv, %{name: remote_name, cookie: cookie} = opts) do
167+
# Allow callers to provide a unique id for the node
168+
# We don't want to generate random ids because it can fill the atom table
169+
id =
170+
case Map.get(opts, :id) do
171+
nil -> nil
172+
suffix -> suffix
173+
end
174+
175+
# Connect to the given remote node
176+
{:ok, peer, name, type} = start_distribution!(remote_name, cookie, id)
153177

154178
new_opts =
155179
opts
@@ -888,11 +912,15 @@ defmodule Mix.Releases.Runtime.Control do
888912
end
889913

890914
@doc false
891-
def start_distribution!(name, cookie) do
915+
def start_distribution!(name, cookie, suffix \\ nil) do
892916
{peer, name, type} =
893917
case name_components(name) do
918+
%{name: name, full: full_name, host: host, type: type} when not is_nil(suffix) ->
919+
{full_name, suffix_name_long(name, host, suffix), type}
894920
%{name: name, full: full_name, host: host, type: type} ->
895-
{full_name, suffix_name(name, host), type}
921+
{full_name, suffix_name_long(name, host), type}
922+
%{name: name, full: full_name, type: type} when not is_nil(suffix) ->
923+
{full_name, suffix_name(name, suffix), type}
896924
%{name: name, full: full_name, type: type} ->
897925
{full_name, suffix_name(name), type}
898926
{:error, reason} ->
@@ -938,8 +966,13 @@ defmodule Mix.Releases.Runtime.Control do
938966
end
939967
end
940968

941-
defp suffix_name(name), do: String.to_atom("#{name}_maint_")
942-
defp suffix_name(name, host), do: String.to_atom("#{name}_maint_@#{host}")
969+
defp suffix_name(name, suffix \\ nil)
970+
defp suffix_name(name, nil), do: String.to_atom("#{name}_maint_")
971+
defp suffix_name(name, suffix), do: String.to_atom("#{name}_#{suffix}")
972+
973+
defp suffix_name_long(name, host, suffix \\ nil)
974+
defp suffix_name_long(name, host, nil), do: String.to_atom("#{name}_maint_@#{host}")
975+
defp suffix_name_long(name, host, suffix), do: String.to_atom("#{name}_#{suffix}@#{host}")
943976

944977
## Helpers
945978

0 commit comments

Comments
 (0)