@@ -39,9 +39,9 @@ defmodule Terrarium.Runtime do
3939 :telemetry . span ( [ :terrarium , :replicate ] , % { sandbox: sandbox , otp_version: otp_version } , fn ->
4040 with :ok <- ensure_mise ( sandbox ) ,
4141 { :ok , dest } <- resolve_dest ( sandbox , dest ) ,
42- { :ok , erl_path } <- install_erlang ( sandbox , otp_version ) ,
42+ { :ok , runtime } <- install_erlang ( sandbox , otp_version ) ,
4343 :ok <- deploy_code ( sandbox , dest ) ,
44- { :ok , pid , node } <- start_peer ( sandbox , erl_path , dest , opts ) do
44+ { :ok , pid , node } <- start_peer ( sandbox , runtime , dest , opts ) do
4545 Logger . info ( "Runtime started in sandbox" ,
4646 sandbox_id: sandbox . id ,
4747 node: node ,
@@ -132,28 +132,38 @@ defmodule Terrarium.Runtime do
132132 defp install_erlang ( sandbox , otp_version ) do
133133 remote_home = resolve_remote_home ( sandbox )
134134 mise = "#{ remote_home } /.local/bin/mise"
135+ elixir_version = System . version ( )
135136
136- Logger . info ( "Installing Erlang #{ otp_version } via mise" , sandbox_id: sandbox . id )
137+ Logger . info ( "Installing Erlang #{ otp_version } and Elixir #{ elixir_version } via mise" ,
138+ sandbox_id: sandbox . id
139+ )
137140
138- case Terrarium . exec ( sandbox , "#{ mise } install erlang@#{ otp_version } " , timeout: 600_000 ) do
139- { :ok , % { exit_code: 0 } } ->
140- # Get the install path to find the erl binary
141- case Terrarium . exec ( sandbox , "#{ mise } where erlang@#{ otp_version } " ) do
142- { :ok , % { exit_code: 0 , stdout: path } } ->
143- erl_path = Path . join ( String . trim ( path ) , "bin/erl" )
144- Logger . info ( "Erlang #{ otp_version } ready" , sandbox_id: sandbox . id , erl_path: erl_path )
145- { :ok , erl_path }
141+ install_cmd = "#{ mise } install erlang@#{ otp_version } elixir@#{ elixir_version } "
146142
147- { :ok , % { exit_code: code , stderr: stderr } } ->
148- { :error , { :mise_where_failed , code , stderr } }
143+ case Terrarium . exec ( sandbox , install_cmd , timeout: 600_000 ) do
144+ { :ok , % { exit_code: 0 } } ->
145+ with { :ok , % { exit_code: 0 , stdout: erl_where } } <-
146+ Terrarium . exec ( sandbox , "#{ mise } where erlang@#{ otp_version } " ) ,
147+ { :ok , % { exit_code: 0 , stdout: elixir_where } } <-
148+ Terrarium . exec ( sandbox , "#{ mise } where elixir@#{ elixir_version } " ) do
149+ erl_path = Path . join ( String . trim ( erl_where ) , "bin/erl" )
150+ elixir_lib = Path . join ( String . trim ( elixir_where ) , "lib" )
151+
152+ Logger . info ( "Runtime ready" ,
153+ sandbox_id: sandbox . id ,
154+ erl_path: erl_path ,
155+ elixir_lib: elixir_lib
156+ )
149157
150- { :error , reason } ->
151- { :error , reason }
158+ { :ok , % { erl_path: erl_path , elixir_lib: elixir_lib } }
159+ else
160+ { :ok , % { exit_code: code , stderr: stderr } } -> { :error , { :mise_where_failed , code , stderr } }
161+ { :error , reason } -> { :error , reason }
152162 end
153163
154164 { :ok , % { exit_code: code , stderr: stderr } } ->
155- Logger . error ( "Erlang installation failed" , sandbox_id: sandbox . id , reason: stderr )
156- { :error , { :erlang_install_failed , code , stderr } }
165+ Logger . error ( "Installation failed" , sandbox_id: sandbox . id , reason: stderr )
166+ { :error , { :install_failed , code , stderr } }
157167
158168 { :error , reason } ->
159169 { :error , reason }
@@ -172,12 +182,20 @@ defmodule Terrarium.Runtime do
172182 # ============================================================================
173183
174184 defp deploy_code ( sandbox , dest ) do
185+ # Only deploy application code paths, not OTP or Elixir stdlib.
186+ # Those are already available on the remote via mise.
187+ otp_lib = :code . lib_dir ( ) |> List . to_string ( )
188+ elixir_lib = :code . lib_dir ( :elixir ) |> List . to_string ( ) |> Path . dirname ( )
189+
175190 paths =
176191 :code . get_path ( )
177192 |> Enum . map ( & List . to_string / 1 )
178193 |> Enum . filter ( & File . dir? / 1 )
194+ |> Enum . reject ( fn p ->
195+ String . starts_with? ( p , otp_lib ) or String . starts_with? ( p , elixir_lib )
196+ end )
179197
180- Logger . debug ( "Creating tarball from #{ length ( paths ) } code paths" , sandbox_id: sandbox . id )
198+ Logger . debug ( "Creating tarball from #{ length ( paths ) } code paths (app only) " , sandbox_id: sandbox . id )
181199
182200 tarball_path = Path . join ( System . tmp_dir! ( ) , "terrarium_deploy_#{ System . unique_integer ( [ :positive ] ) } .tar.gz" )
183201 file_args = Enum . flat_map ( paths , fn path -> [ "-C" , Path . dirname ( path ) , Path . basename ( path ) ] end )
@@ -215,12 +233,18 @@ defmodule Terrarium.Runtime do
215233 # Peer Node
216234 # ============================================================================
217235
218- defp start_peer ( sandbox , erl_path , dest , opts ) do
236+ defp start_peer ( sandbox , runtime , dest , opts ) do
237+ # Include app code + Elixir stdlib paths
238+ pa_paths = [
239+ "#{ dest } /ebin" ,
240+ "#{ runtime . elixir_lib } /*/ebin"
241+ ]
242+
219243 peer_opts =
220244 opts
221245 |> Keyword . take ( [ :name , :env , :erl_args ] )
222- |> Keyword . put ( :pa_paths , [ " #{ dest } /ebin" ] )
223- |> Keyword . put ( :erl_cmd , erl_path )
246+ |> Keyword . put ( :pa_paths , pa_paths )
247+ |> Keyword . put ( :erl_cmd , runtime . erl_path )
224248
225249 Terrarium.Peer . start ( sandbox , peer_opts )
226250 end
0 commit comments