Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions lib/ex_loader.ex
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,8 @@ defmodule ExLoader do
def load_apps(tarball, apps), do: load_apps(tarball, apps, node())

def load_apps(tarball, apps, remote_node) do
with {:ok, dst} <- ExLoader.File.copy(remote_node, tarball),
:ok <- ExLoader.File.uncompress(remote_node, dst) do
ExLoader.Release.load(remote_node, Path.dirname(dst), apps)
else
case ExLoader.File.uncompress(remote_node, tarball) do
{:ok, dst} -> ExLoader.Release.load(remote_node, Path.dirname(dst), apps)
err -> err
end
end
Expand Down
42 changes: 29 additions & 13 deletions lib/file.ex
Original file line number Diff line number Diff line change
Expand Up @@ -31,27 +31,43 @@ defmodule ExLoader.File do
end

def uncompress(remote_node, tarball) do
parent = Path.dirname(tarball)
{:ok, dst} = mkdir_p(remote_node, tarball)

{_, status} =
:rpc.call(remote_node, System, :cmd, [
"tar",
["zxvf", tarball],
[cd: parent, stderr_to_stdout: true]
])
# uncompress in local with erlang stdlib
file =
case read(tarball) do
{:ok, file} -> file
err -> throw(err)
end

case :erl_tar.extract({:binary, file}, [:memory, :compressed]) do
{:ok, files} ->
Enum.each(files, fn {filename, raw} ->
file_path = Path.join([Path.dirname(dst), filename])

case status do
0 ->
:ok
with :ok <- :rpc.call(remote_node, :filelib, :ensure_dir, [to_charlist(file_path)]),
{:ok, _} <- write(remote_node, file_path, raw) do
:ok
else
err -> throw(err)
end
end)

_ ->
{:ok, dst}

{:error, _} ->
{:error, %{msg: "failed to uncompress the release tarball: #{tarball}", reason: :badfile}}
end
catch
err -> err
end

defp mkdir_p(remote_node, src) do
dst = "/tmp/#{@prefix}.#{Nanoid.generate()}/#{Path.basename(src)}"
result = :rpc.call(remote_node, File, :mkdir_p, [Path.dirname(dst)])

# erlang filelib:ensure_dir, must end with "/"
target_dir_path = to_charlist("#{Path.dirname(dst)}/")
result = :rpc.call(remote_node, :filelib, :ensure_dir, [target_dir_path])

case result do
:ok ->
Expand All @@ -69,7 +85,7 @@ defmodule ExLoader.File do
end

defp write(remote_node, dst, bin) do
result = :rpc.call(remote_node, File, :write, [dst, bin])
result = :rpc.call(remote_node, :file, :write_file, [to_charlist(dst), bin])

case result do
:ok ->
Expand Down
24 changes: 13 additions & 11 deletions lib/release.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ defmodule ExLoader.Release do
defp get_rel_file(remote_node, base) do
rel_file =
remote_node
|> :rpc.call(Path, :wildcard, ["#{base}/releases/*.rel"])
|> :rpc.call(:filelib, :wildcard, [to_charlist("#{base}/releases/**/*.rel")])
|> List.first()

case rel_file do
Expand All @@ -30,7 +30,7 @@ defmodule ExLoader.Release do
{:release, {_, ver}, _, apps} = read_config(remote_node, rel_file)

started_apps =
Enum.map(:rpc.call(remote_node, Application, :started_applications, []), fn {app, _, _} ->
Enum.map(:rpc.call(remote_node, :application, :loaded_applications, []), fn {app, _, _} ->
app
end)

Expand All @@ -39,7 +39,7 @@ defmodule ExLoader.Release do

defp add_paths(remote_node, base, apps) do
paths =
Enum.map(get_paths(base, apps), fn p ->
Enum.map(get_paths(base, apps, remote_node), fn p ->
:rpc.call(remote_node, :code, :add_path, [to_charlist(p)])
p
end)
Expand All @@ -54,7 +54,7 @@ defmodule ExLoader.Release do
|> read_config(sys_config)
|> Enum.each(fn {app, data} ->
Enum.each(data, fn {k, v} ->
:rpc.call(remote_node, Application, :put_env, [app, k, v, [persistent: true]])
:rpc.call(remote_node, :application, :set_env, [app, k, v, [persistent: true]])
end)
end)

Expand All @@ -63,25 +63,27 @@ defmodule ExLoader.Release do

defp load_apps(remote_node, apps) do
Enum.each(apps, fn app ->
:rpc.call(remote_node, Application, :ensure_all_started, [app])
:rpc.call(remote_node, :application, :ensure_all_started, [app])
end)
end

defp get_paths(base, apps) do
defp get_paths(base, apps, remote_node) do
apps
|> Enum.map(fn app ->
parent = Path.join(base, "lib/#{elem(app, 0)}-#{elem(app, 1)}")

parent
|> File.ls!()
|> Enum.map(&Path.join(parent, &1))
|> Enum.filter(fn p -> File.dir?(p) and Path.basename(p) != "priv" end)
{:ok, filenames} = :rpc.call(remote_node, :file, :list_dir, [to_charlist(parent)])

Enum.map(filenames, &Path.join(parent, &1))
|> Enum.filter(fn p ->
:rpc.call(remote_node, :filelib, :is_dir, [to_charlist(p)]) and Path.basename(p) != "priv"
end)
end)
|> List.flatten()
end

defp read_config(remote_node, file) do
content = :rpc.call(remote_node, File, :read!, [file])
{:ok, content} = :rpc.call(remote_node, :file, :read_file, [file])
{:ok, tokens, _} = :erl_scan.string(to_charlist(content))
{:ok, [form]} = :erl_parse.parse_exprs(tokens)
{:value, v, _} = :erl_eval.expr(form, [])
Expand Down
40 changes: 20 additions & 20 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
%{
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"},
"certifi": {:hex, :certifi, "2.0.0", "a0c0e475107135f76b8c1d5bc7efb33cd3815cb3cf3dea7aefdd174dabead064", [:rebar3], [], "hexpm"},
"cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"},
"cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], [], "hexpm"},
"credo": {:hex, :credo, "0.8.10", "261862bb7363247762e1063713bb85df2bbd84af8d8610d1272cd9c1943bba63", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm"},
"earmark": {:hex, :earmark, "1.2.4", "99b637c62a4d65a20a9fb674b8cffb8baa771c04605a80c911c4418c69b75439", [:mix], [], "hexpm"},
"ex_doc": {:hex, :ex_doc, "0.18.2", "993e0a95e9fbb790ac54ea58e700b45b299bd48bc44b4ae0404f28161f37a83e", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"},
"fake_server": {:hex, :fake_server, "1.4.0", "d29af7f02b49c60b5cd96f1c66560579c055036dc33d8e6ed8ed59f30c1ecda4", [:mix], [{:cowboy, "~> 1.1", [hex: :cowboy, repo: "hexpm", optional: false]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
"hackney": {:hex, :hackney, "1.11.0", "4951ee019df102492dabba66a09e305f61919a8a183a7860236c0fde586134b6", [:rebar3], [{:certifi, "2.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
"httpoison": {:hex, :httpoison, "1.0.0", "1f02f827148d945d40b24f0b0a89afe40bfe037171a6cf70f2486976d86921cd", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
"idna": {:hex, :idna, "5.1.0", "d72b4effeb324ad5da3cab1767cb16b17939004e789d8c0ad5b70f3cea20c89a", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
"jason": {:hex, :jason, "1.0.0", "0f7cfa9bdb23fed721ec05419bcee2b2c21a77e926bce0deda029b5adc716fe2", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"},
"nanoid": {:hex, :nanoid, "1.0.1", "4f9bcecfbc0046795e1084e85b3d25da3721b36b949a672736492c5dfe901062", [:mix], [], "hexpm"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},
"pre_commit_hook": {:hex, :pre_commit_hook, "1.2.0", "cdd3448dfe05df5ceac3427c9784af2cb2bbff05876e0e3a6e002c5163eb5f7a", [:mix], [], "hexpm"},
"ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], [], "hexpm"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm"},
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"},
"certifi": {:hex, :certifi, "2.0.0", "a0c0e475107135f76b8c1d5bc7efb33cd3815cb3cf3dea7aefdd174dabead064", [:rebar3], [], "hexpm", "fdc6066ceeccb3aa14049ab6edf0b9af3b64ae1b0db2a92d5c52146f373bbb1c"},
"cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "f4763bbe08233eceed6f24bc4fcc8d71c17cfeafa6439157c57349aa1bb4f17c"},
"cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], [], "hexpm", "db622da03aa039e6366ab953e31186cc8190d32905e33788a1acb22744e6abd2"},
"credo": {:hex, :credo, "0.8.10", "261862bb7363247762e1063713bb85df2bbd84af8d8610d1272cd9c1943bba63", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm", "f3fe29f8de6be431c7736a933a3897fe9aa45533b1d1358b3691ac8ec4371e8f"},
"earmark": {:hex, :earmark, "1.2.4", "99b637c62a4d65a20a9fb674b8cffb8baa771c04605a80c911c4418c69b75439", [:mix], [], "hexpm", "1b34655872366414f69dd987cb121c049f76984b6ac69f52fff6d8fd64d29cfd"},
"ex_doc": {:hex, :ex_doc, "0.18.2", "993e0a95e9fbb790ac54ea58e700b45b299bd48bc44b4ae0404f28161f37a83e", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm", "eacdfd22d5c7e5f3fda086214c69a8b6ca4298ad90d99f399d591f14eead6a61"},
"fake_server": {:hex, :fake_server, "1.4.0", "d29af7f02b49c60b5cd96f1c66560579c055036dc33d8e6ed8ed59f30c1ecda4", [:mix], [{:cowboy, "~> 1.1", [hex: :cowboy, repo: "hexpm", optional: false]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm", "426ff3d221c273ad09af44fb6893dd6973cde119e7af1382c4f011ac24e0d538"},
"hackney": {:hex, :hackney, "1.11.0", "4951ee019df102492dabba66a09e305f61919a8a183a7860236c0fde586134b6", [:rebar3], [{:certifi, "2.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "bb3cc62ecc10145f8f0965c05083a5278eae7ef1853d340cc9a7a3e27609b9bd"},
"httpoison": {:hex, :httpoison, "1.0.0", "1f02f827148d945d40b24f0b0a89afe40bfe037171a6cf70f2486976d86921cd", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "07967c56199f716ce9adb27415ccea1bd76c44f777dd0a6d4166c3d932f37fdf"},
"idna": {:hex, :idna, "5.1.0", "d72b4effeb324ad5da3cab1767cb16b17939004e789d8c0ad5b70f3cea20c89a", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "fc1a2f7340c422650504b1662f28fdf381f34cbd30664e8491744e52c9511d40"},
"jason": {:hex, :jason, "1.0.0", "0f7cfa9bdb23fed721ec05419bcee2b2c21a77e926bce0deda029b5adc716fe2", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "b96c400e04b7b765c0854c05a4966323e90c0d11fee0483b1567cda079abb205"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm", "7a4c8e1115a2732a67d7624e28cf6c9f30c66711a9e92928e745c255887ba465"},
"nanoid": {:hex, :nanoid, "1.0.1", "4f9bcecfbc0046795e1084e85b3d25da3721b36b949a672736492c5dfe901062", [:mix], [], "hexpm", "0809ff7e0f87d63d23e4f8608a014a2bf734232d7b289ff7809c14453c51cd71"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm", "fec8660eb7733ee4117b85f55799fd3833eb769a6df71ccf8903e8dc5447cfce"},
"pre_commit_hook": {:hex, :pre_commit_hook, "1.2.0", "cdd3448dfe05df5ceac3427c9784af2cb2bbff05876e0e3a6e002c5163eb5f7a", [:mix], [], "hexpm", "257017c59a2c5da127c668d84ccc5efe070297d6892e6f547d76b353c78ac000"},
"ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], [], "hexpm", "6e56493a862433fccc3aca3025c946d6720d8eedf6e3e6fb911952a7071c357f"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm", "4f8805eb5c8a939cf2359367cb651a3180b27dfb48444846be2613d79355d65e"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm", "da1d9bef8a092cc7e1e51f1298037a5ddfb0f657fe862dfe7ba4c5807b551c29"},
}
4 changes: 2 additions & 2 deletions priv/fixture/apps/example_app/Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
RELEASE_FILE=_build/prod/rel/example_app/releases/0.1.0/example_app.tar.gz
RELEASE_FILE=_build/prod/example_app-0.1.0.tar.gz
TARGET_DIR=../tarball
FILE_NAME=$(shell basename $(RELEASE_FILE))
build:
@mix deps.get
@MIX_ENV=prod mix compile
@MIX_ENV=prod mix release --env=prod
@MIX_ENV=prod mix release --overwrite
@cp $(RELEASE_FILE) $(TARGET_DIR)/$(FILE_NAME)
7 changes: 6 additions & 1 deletion priv/fixture/apps/example_app/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ defmodule ExampleApp.MixProject do
version: "0.1.0",
elixir: "~> 1.6",
start_permanent: Mix.env() == :prod,
deps: deps()
deps: deps(),
releases: [
example_app: [
steps: [:assemble, :tar]
]
]
]
end

Expand Down
2 changes: 1 addition & 1 deletion priv/fixture/apps/example_app/mix.lock
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
%{
"distillery": {:hex, :distillery, "1.5.2", "eec18b2d37b55b0bcb670cf2bcf64228ed38ce8b046bb30a9b636a6f5a4c0080", [:mix], [], "hexpm"},
"distillery": {:hex, :distillery, "1.5.2", "eec18b2d37b55b0bcb670cf2bcf64228ed38ce8b046bb30a9b636a6f5a4c0080", [:mix], [], "hexpm", "cf01ab32ac53d131ce6efafa20b62ff859ff8ca474b5a4a8b45d835a1b76a851"},
}
4 changes: 2 additions & 2 deletions priv/fixture/apps/example_complex_app/Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
RELEASE_FILE=_build/prod/rel/example_complex_app/releases/0.1.0/example_complex_app.tar.gz
RELEASE_FILE=_build/prod/example_complex_app-0.1.0.tar.gz
TARGET_DIR=../tarball
FILE_NAME=$(shell basename $(RELEASE_FILE))
build:
@mix deps.get
@MIX_ENV=prod mix compile
@MIX_ENV=prod mix release --env=prod
@MIX_ENV=prod mix release --overwrite
@cp $(RELEASE_FILE) $(TARGET_DIR)/$(FILE_NAME)
9 changes: 8 additions & 1 deletion priv/fixture/apps/example_complex_app/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@ defmodule ExampleComplexApp.MixProject do
def project do
[
apps_path: "apps",
version: "0.1.0",
start_permanent: Mix.env() == :prod,
deps: deps()
deps: deps(),
releases: [
example_complex_app: [
applications: [app1: :permanent, app2: :permanent],
steps: [:assemble, :tar]
]
]
]
end

Expand Down
Loading