Packages

Load a single beam file, an app (a set of beams), or an erlang release (a set of apps) to a node.

Current section

Files

Jump to
ex_loader lib file.ex
Raw

lib/file.ex

defmodule ExLoader.File do
@moduledoc """
copy file to remote nodes.
"""
@prefix Atom.to_string(ExLoader.MixProject.project()[:app])
def copy(remote_node, src) do
with {:ok, bin} <- read(src),
{:ok, dst} <- mkdir_p(remote_node, src),
{:ok, dst} <- write(remote_node, dst, bin) do
{:ok, dst}
else
err -> err
end
end
def uncompress(remote_node, tarball) do
parent = Path.dirname(tarball)
{_, status} =
:rpc.call(remote_node, System, :cmd, [
"tar",
["zxvf", tarball],
[cd: parent, stderr_to_stdout: true]
])
case status do
0 ->
:ok
_ ->
{:error, %{msg: "failed to uncompress the release tarball: #{tarball}", reason: :badfile}}
end
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)])
case result do
:ok ->
{:ok, dst}
{:error, reason} ->
{:error,
%{
msg:
"cannot copy file to target node due to dir creation failure for #{dst}. Reason: #{
inspect(reason)
}"
}}
end
end
defp write(remote_node, dst, bin) do
result = :rpc.call(remote_node, File, :write, [dst, bin])
case result do
:ok ->
{:ok, dst}
{:error, reason} ->
{:error,
%{msg: "cannot write to file #{dst}. Reason: #{inspect(reason)}", reason: reason}}
end
end
defp read(src) do
case File.read(src) do
{:ok, bin} ->
{:ok, bin}
{:error, reason} ->
{:error, %{msg: "cannot read file #{src}. Reason: #{inspect(reason)}", reason: reason}}
end
end
end