Deployment and lifecycle management for Nix
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: replace erlexec with Rexec, a lightweight Rust port wrapper

Co-Authored-By: Claude <noreply@anthropic.com>

https://claude.ai/code/session_01KdA89BsP8CMZ4Wk4bEbkuPj

authored by

Claude
Claude
and committed by
Adam C. Stephens
23515021 17d52b83

+64 -61
+1 -1
.iex-garden.exs
··· 1 - Application.ensure_all_started([:erlexec, :exsync, :garden]) 1 + Application.ensure_all_started([:exsync, :garden]) 2 2 3 3 IEx.configure( 4 4 inspect: [
+1 -1
.iex-server.exs
··· 5 5 |> Map.get(:org_id) 6 6 |> Sower.Repo.put_org_id() 7 7 else 8 - Application.ensure_all_started([:erlexec, :exsync]) 8 + Application.ensure_all_started([:exsync]) 9 9 end 10 10 IEx.configure( 11 11 inspect: [
+1 -1
.iex.exs
··· 4 4 |> Map.get(:org_id) 5 5 |> Sower.Repo.put_org_id() 6 6 else 7 - Application.ensure_all_started([:erlexec, :exsync]) 7 + Application.ensure_all_started([:exsync]) 8 8 end 9 9 10 10 IEx.configure(
+1 -8
apps/nix/lib/nix/build.ex
··· 96 96 drv_path: state.build.drv_path 97 97 ) 98 98 99 - {:ok, pid, ospid} = 100 - :exec.run_link( 101 - cmd, 102 - [ 103 - :stdout, 104 - :stderr 105 - ] 106 - ) 99 + {:ok, pid, ospid} = Rexec.run_link(cmd) 107 100 108 101 state = %{ 109 102 state
+10 -10
apps/nix/lib/nix/cache/attic.ex
··· 106 106 end 107 107 108 108 defp run_with_stdin(cmd, stdin_data) do 109 - case :exec.run(cmd, [:stdin, :stdout, :stderr, :monitor]) do 110 - {:ok, _pid, ospid} -> 111 - :ok = :exec.send(ospid, stdin_data) 112 - :ok = :exec.send(ospid, :eof) 113 - await_completion(ospid, [], []) 109 + case Rexec.run(cmd) do 110 + {:ok, pid, ospid} -> 111 + :ok = Rexec.send(pid, stdin_data) 112 + :ok = Rexec.send(pid, :eof) 113 + await_completion(pid, ospid, [], []) 114 114 115 115 {:error, reason} -> 116 116 {:error, %{exit_status: 1, stderr: to_string(reason), stdout: ""}} 117 117 end 118 118 end 119 119 120 - defp await_completion(ospid, stdout, stderr) do 120 + defp await_completion(pid, ospid, stdout, stderr) do 121 121 receive do 122 122 {:stdout, ^ospid, data} -> 123 - await_completion(ospid, [data | stdout], stderr) 123 + await_completion(pid, ospid, [data | stdout], stderr) 124 124 125 125 {:stderr, ^ospid, data} -> 126 - await_completion(ospid, stdout, [data | stderr]) 126 + await_completion(pid, ospid, stdout, [data | stderr]) 127 127 128 128 {:DOWN, _ospid, :process, _pid, :normal} -> 129 129 {:ok, finalize_output(stdout, stderr)} 130 130 131 - {:DOWN, _ospid, :process, _pid, {:exit_status, status}} -> 131 + {:DOWN, _ospid, :process, _pid, {:shutdown, {:exit_status, status}}} -> 132 132 {:error, finalize_output(stdout, stderr) |> Map.put(:exit_status, status)} 133 133 after 134 134 # 30 minute timeout for large uploads 135 135 30 * 60 * 1000 -> 136 - :exec.kill(ospid, :sigterm) 136 + Rexec.kill(pid, :sigterm) 137 137 {:error, %{exit_status: 1, stderr: "timeout", stdout: ""}} 138 138 end 139 139 end
+2 -9
apps/nix/lib/nix/eval.ex
··· 121 121 122 122 Logger.debug(msg: "Running command", cmd: Enum.join(cmd, " ")) 123 123 124 - {:ok, pid, ospid} = 125 - :exec.run_link( 126 - cmd, 127 - [ 128 - :stdout, 129 - :stderr 130 - ] 131 - ) 124 + {:ok, pid, ospid} = Rexec.run_link(cmd) 132 125 133 126 state = %{ 134 127 state ··· 164 157 active_memory_kb: mem 165 158 ) 166 159 167 - :exec.kill(state.pid, :sigterm) 160 + Rexec.kill(state.pid, :sigterm) 168 161 169 162 true -> 170 163 :ok
+10 -6
apps/nix/lib/nix/store.ex
··· 4 4 def realize(path) do 5 5 Logger.debug(msg: "Realizing path", path: path) 6 6 7 - {:ok, _} = Application.ensure_all_started(:erlexec) 7 + case System.find_executable("nix-store") do 8 + nil -> 9 + {:error, "nix-store command not found in PATH"} 8 10 9 - cmd = ~c"nix-store --realize #{path}" 11 + nix_store -> 12 + cmd = [nix_store, "--realize", path] 10 13 11 - Process.flag(:trap_exit, true) 12 - {:ok, pid, ospid} = :exec.run_link(cmd, [:stdout, :stderr]) 14 + Process.flag(:trap_exit, true) 15 + {:ok, pid, ospid} = Rexec.run_link(cmd) 13 16 14 - collect_output(pid, ospid, []) 17 + collect_output(pid, ospid, []) 18 + end 15 19 end 16 20 17 21 defp collect_output(pid, ospid, lines) do ··· 27 31 {:EXIT, ^pid, :normal} -> 28 32 {:ok, Enum.reverse(lines)} 29 33 30 - {:EXIT, ^pid, {:exit_status, status}} -> 34 + {:EXIT, ^pid, {:shutdown, {:exit_status, status}}} -> 31 35 {:error, status} 32 36 end 33 37 end
+1 -1
apps/nix/mix.exs
··· 28 28 defp deps do 29 29 [ 30 30 {:cuid2_ex, "~> 0.2"}, 31 - {:erlexec, "~> 2.0"}, 32 31 {:jason, "~> 1.0"}, 32 + {:rexec, git: "https://codeberg.org/adamcstephens/rexec.git", branch: "main"}, 33 33 {:typedstruct, "~> 0.5.4"} 34 34 ] 35 35 end
-1
apps/sower_cli/lib/sower_cli/build.ex
··· 80 80 defp run_steps([:eval | rest], %__MODULE__{} = state) do 81 81 Output.step("Evaluating #{state.request.path}") 82 82 83 - Application.ensure_all_started([:erlexec]) 84 83 Output.init(debug: state.flags.debug) 85 84 86 85 opts = [
+1
mix.lock
··· 66 66 "quantum": {:hex, :quantum, "3.5.3", "ee38838a07761663468145f489ad93e16a79440bebd7c0f90dc1ec9850776d99", [:mix], [{:crontab, "~> 1.1", [hex: :crontab, repo: "hexpm", optional: false]}, {:gen_stage, "~> 0.14 or ~> 1.0", [hex: :gen_stage, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:telemetry_registry, "~> 0.2", [hex: :telemetry_registry, repo: "hexpm", optional: false]}], "hexpm", "500fd3fa77dcd723ed9f766d4a175b684919ff7b6b8cfd9d7d0564d58eba8734"}, 67 67 "req": {:hex, :req, "0.5.17", "0096ddd5b0ed6f576a03dde4b158a0c727215b15d2795e59e0916c6971066ede", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "0b8bc6ffdfebbc07968e59d3ff96d52f2202d0536f10fef4dc11dc02a2a43e39"}, 68 68 "rewrite": {:hex, :rewrite, "1.3.0", "67448ba7975690b35ba7e7f35717efcce317dbd5963cb0577aa7325c1923121a", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}, {:text_diff, "~> 0.1", [hex: :text_diff, repo: "hexpm", optional: false]}], "hexpm", "d111ac7ff3a58a802ef4f193bbd1831e00a9c57b33276e5068e8390a212714a5"}, 69 + "rexec": {:git, "https://codeberg.org/adamcstephens/rexec.git", "b497afe9684ee58d84194fcf9e2fe9bdad6e0c6b", [branch: "main"]}, 69 70 "rustler": {:hex, :rustler, "0.36.2", "6c2142f912166dfd364017ab2bf61242d4a5a3c88e7b872744642ae004b82501", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:toml, "~> 0.7", [hex: :toml, repo: "hexpm", optional: false]}], "hexpm", "93832a6dbc1166739a19cd0c25e110e4cf891f16795deb9361dfcae95f6c88fe"}, 70 71 "shortuuid": {:hex, :shortuuid, "4.1.0", "6f59470b78169c84a0cedbbe3fd4e83f0837a59877a4e1a7c0709916d54239e2", [:mix], [], "hexpm", "7336719118b3cca1ac73e95810199b0b9b7d00f9d71bd2c2d27fed4c4f74388e"}, 71 72 "slipstream": {:hex, :slipstream, "1.2.2", "6b07124ac5f62a50327aa38c84edd0284920ac8aba548e04738827838f233ed0", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mint_web_socket, "~> 0.2 or ~> 1.0", [hex: :mint_web_socket, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.1 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ccb873ddb21aadb37c5c7745014febe6da0aa2cef0c4e73e7d08ce11d18aacd0"},
-2
nix/nixos/garden.nix
··· 170 170 ]; 171 171 172 172 environment = { 173 - # erlexec needs a shell 174 - SHELL = lib.getExe pkgs.bash; 175 173 # load code on demand, reduces memory requirement 176 174 RELEASE_MODE = "interactive"; 177 175
+17 -16
nix/packages/deps.nix
··· 426 426 in 427 427 drv; 428 428 429 - erlexec = 430 - let 431 - version = "2.2.2"; 432 - drv = buildRebar3 { 433 - inherit version; 434 - name = "erlexec"; 435 - 436 - src = fetchHex { 437 - inherit version; 438 - pkg = "erlexec"; 439 - sha256 = "5e8e3c3773113785361b3b55218d92f7e91509cc9d679bf67c5c3703b394c900"; 440 - }; 441 - }; 442 - in 443 - drv; 444 - 445 429 esbuild = 446 430 let 447 431 version = "0.10.0"; ··· 1240 1224 mime 1241 1225 plug 1242 1226 ]; 1227 + }; 1228 + in 1229 + drv; 1230 + 1231 + rexec = 1232 + let 1233 + version = "0.1.0"; 1234 + drv = buildMix { 1235 + inherit version; 1236 + name = "rexec"; 1237 + appConfigPath = ../../config; 1238 + 1239 + src = builtins.fetchGit { 1240 + url = "https://codeberg.org/adamcstephens/rexec.git"; 1241 + rev = "b497afe9684ee58d84194fcf9e2fe9bdad6e0c6b"; 1242 + allRefs = true; 1243 + }; 1243 1244 }; 1244 1245 in 1245 1246 drv;
+1 -5
nix/packages/part.nix
··· 26 26 }; 27 27 28 28 server = pkgs.callPackage ./server.nix { 29 - inherit 30 - beamPackages 31 - version 32 - sowerServicesHook 33 - ; 29 + inherit beamPackages version sowerServicesHook; 34 30 35 31 sowerLib = self.lib; 36 32 };
+18
nix/packages/umbrella-deps.nix
··· 35 35 # env.DIAGNOSTIC = "1"; 36 36 # }); 37 37 38 + rexec = prev.rexec.override ( 39 + old: 40 + let 41 + native = rustPlatform.buildRustPackage { 42 + pname = "rexec-native"; 43 + version = old.version; 44 + src = "${old.src}/native/rexec_native"; 45 + cargoLock.lockFile = "${old.src}/native/rexec_native/Cargo.lock"; 46 + }; 47 + in 48 + { 49 + preBuild = '' 50 + mkdir -p priv/ 51 + cp ${native}/bin/rexec_native priv/ 52 + ''; 53 + } 54 + ); 55 + 38 56 esbuild = prev.esbuild.override (old: { 39 57 patches = [ ./esbuild-loadpaths.patch ]; 40 58 });