voughtdq

voughtdq

Escript: can not load argon2_nif - wrong approach for CLI?

I’m trying to create a command line utility for creating administrative users in a back office application.

defmodule Admin.CLI do

  def main(args) do
    handle_command(args)
  end

  def handle_command(["createadmin" | rest]) do
    {opts, _, _} = OptionParser.parse(rest, switches: [username: :string, password: :string],
      aliases: [u: :username, p: :password])

    username = Keyword.get(opts, :username) || raise "You must supply a username"
    password = Keyword.get(opts, :password) || raise "You must supply a password"

    case Admin.create_user(%{"username" => username, "password" => password}) do
      {:ok, _user} ->
        IO.puts("User #{username} created with password #{password}")
      {:error, _} ->
        IO.puts(:stderr, "Error creating user.")
    end
  end

  def handle_command(_) do
    IO.puts(:stderr, "Invalid command.")
  end
end

But this is the output that I receive when running the command:

$ ./admin createadmin --username test --password test
[warn] The on_load function for module Elixir.Argon2.Base returned:
{:function_clause, [{:filename, :join, [{:error, :bad_name}, 'argon2_nif'], [file: 'filename.erl', line: 446]}, {Argon2.Base, :load_nif, 0, [file: 'lib/argon2/base.ex', line: 115]}, {Argon2.Base, :init, 0, [file: 'lib/argon2/base.ex', ...]}, {:code_server, :"-handle_on_load/5-fun-0-", 1, [...]}]}

[error] Process #PID<0.243.0> raised an exception
** (FunctionClauseError) no function clause matching in :filename.join/2
    (stdlib) filename.erl:446: :filename.join({:error, :bad_name}, 'argon2_nif')
    (argon2_elixir) lib/argon2/base.ex:115: Argon2.Base.load_nif/0
    (argon2_elixir) lib/argon2/base.ex:14: Argon2.Base.init/0
    (kernel) code_server.erl:1340: anonymous fn/1 in :code_server.handle_on_load/5
** (UndefinedFunctionError) function Argon2.Base.hash_password/3 is undefined (module Argon2.Base is not available)
    (argon2_elixir) Argon2.Base.hash_password("test", <<158, 41, 41, 255, 119, 126, 67, 223, 90, 157, 199, 83, 101, 28, 67, 206>>, [])
    (argon2_elixir) lib/argon2.ex:140: Argon2.add_hash/2
    (admin) lib/admin/user.ex:30: Admin.User.maybe_add_hash/1
    (admin) lib/admin.ex:14: Admin.create_user/1
    (admin) lib/admin/cli.ex:14: Admin.CLI.handle_command/1
    (elixir) lib/kernel/cli.ex:121: anonymous fn/3 in Kernel.CLI.exec_fun/2

When running with the same input from iex -S mix, it works as expected:

iex(1)> Admin.CLI.handle_command(["createadmin", "--username", "test", "--password", "test"])
User test created with password test
[debug] QUERY OK db=25.1ms decode=0.8ms queue=0.6ms
INSERT INTO "users" ("password_hash","username") VALUES ($1,$2) RETURNING "id" ["$argon2id$v=19$m=131072,t=8,p=4$dXaxDD2S7LG2sAaxfj8u9w$iJw1bEMSwZCPS3jIFZZ4Fzg/5sGf0hSEh8izr1hlyCY", "test"]

Is my approach wrong here? Should the escript just be sending messages to a handler process that’s already running inside the application?

Marked As Solved

NobbZ

NobbZ

You can not use NIFs in an escript.


edit

Strictly speaking, you can’t use priv_dir in an escript, which most NIFs rely on to ship the shared object which contains the actual NIF.

Where Next?

Popular in Questions Top

gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
sacepums
Hey guys. I'm new to elixir and im really stocked about it. But I ran into a bit of problem - I need to convert a date sting, for examp...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
hpopp
To simplify some tasks at work, I wrote and published this package yesterday. It’s a simple macro that enables Access behaviour on struct...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New

Other popular topics Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
William
I would like to know that is there any online source for learning Phoenix Framework for building E-Commerce Store? Any advantage on build...
New
AstonJ
You’re a programmer, so you don’t need spoon feeding with the conventional drivel about “this is an integer.” No. You need to know what’s...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

We're in Beta

About us Mission Statement