bitwalker / distillery

Simplify deployments in Elixir with OTP releases!
MIT License
2.97k stars 398 forks source link

Release does not properly package all dependencies #671

Closed Overbryd closed 5 years ago

Overbryd commented 5 years ago

Outline

I found a bug that hints that dependencies are not properly packaged and are missing some erlang modules.

The nasty thing about this bug is, it only shows in the release but not development or anywhere else.

Read on to reproduce.

Precheck

Environment

$ elixir --version
Erlang/OTP 21 [erts-10.3.5] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe] [dtrace]

Elixir 1.8.2 (compiled with Erlang/OTP 21)

Steps to reproduce

$ mix new dependency_bug --sup
$ cd dependency_bug
  defp deps do
    [
      {:flare, git: "https://github.com/lpgauth/flare.git", tag: "0.3.3"},
      {:distillery, "~> 2.0"},
    ]
  end
$ mix deps.get
$ mix release.init
$ iex -S mix
iex(1)> Application.ensure_all_started(:flare)
{:ok, []}

tl;dr We are exiting with exception error: undefined function kpro_req_lib:make/3 in function flare_api_versions:api_versions/1

That hints, the release is missing the kpro_req_lib module from the sub dependency.

$ MIX_ENV=prod mix release
$ _build/prod/rel/dependency_bug/bin/dependency_bug console
Erlang/OTP 21 [erts-10.3.5] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe] [dtrace]

=CRASH REPORT==== 27-May-2019::19:46:22.966625 ===
  crasher:
    initial call: supervisor:flare_sup/1
    pid: <0.896.0>
    registered_name: []
    exception error: undefined function kpro_req_lib:make/3
      in function  flare_api_versions:api_versions/1 (/Users/lukas/Work/hibase/dependency_bug/deps/flare/src/flare_api_versions.erl, line 66)
      in call from flare_api_versions:init/0 (/Users/lukas/Work/hibase/dependency_bug/deps/flare/src/flare_api_versions.erl, line 22)
      in call from flare_sup:init/1 (/Users/lukas/Work/hibase/dependency_bug/deps/flare/src/flare_sup.erl, line 25)
      in call from supervisor:init/1 (supervisor.erl, line 295)
      in call from gen_server:init_it/2 (gen_server.erl, line 374)
      in call from gen_server:init_it/6 (gen_server.erl, line 342)
    ancestors: [<0.895.0>]
    message_queue_len: 0
    messages: []
    links: [<0.895.0>]
    dictionary: []
    trap_exit: true
    status: running
    heap_size: 1598
    stack_size: 27
    reductions: 1989
  neighbours:

=CRASH REPORT==== 27-May-2019::19:46:22.966635 ===
  crasher:
    initial call: application_master:init/4
    pid: <0.894.0>
    registered_name: []
    exception exit: {{undef,
                         [{kpro_req_lib,make,[api_versions,0,[]],[]},
                          {flare_api_versions,api_versions,1,
                              [{file,
                                   "/Users/lukas/Work/hibase/dependency_bug/deps/flare/src/flare_api_versions.erl"},
                               {line,66}]},
                          {flare_api_versions,init,0,
                              [{file,
                                   "/Users/lukas/Work/hibase/dependency_bug/deps/flare/src/flare_api_versions.erl"},
                               {line,22}]},
                          {flare_sup,init,1,
                              [{file,
                                   "/Users/lukas/Work/hibase/dependency_bug/deps/flare/src/flare_sup.erl"},
                               {line,25}]},
                          {supervisor,init,1,
                              [{file,"supervisor.erl"},{line,295}]},
                          {gen_server,init_it,2,
                              [{file,"gen_server.erl"},{line,374}]},
                          {gen_server,init_it,6,
                              [{file,"gen_server.erl"},{line,342}]},
                          {proc_lib,init_p_do_apply,3,
                              [{file,"proc_lib.erl"},{line,249}]}]},
                     {flare_app,start,[normal,[]]}}
      in function  application_master:init/4 (application_master.erl, line 138)
    ancestors: [<0.893.0>]
    message_queue_len: 1
    messages: [{'EXIT',<0.895.0>,normal}]
    links: [<0.893.0>,<0.796.0>]
    dictionary: []
    trap_exit: true
    status: running
    heap_size: 987
    stack_size: 27
    reductions: 275
  neighbours:

=INFO REPORT==== 27-May-2019::19:46:22.967215 ===
    application: flare
    exited: {{undef,
                 [{kpro_req_lib,make,[api_versions,0,[]],[]},
                  {flare_api_versions,api_versions,1,
                      [{file,
                           "/Users/lukas/Work/hibase/dependency_bug/deps/flare/src/flare_api_versions.erl"},
                       {line,66}]},
                  {flare_api_versions,init,0,
                      [{file,
                           "/Users/lukas/Work/hibase/dependency_bug/deps/flare/src/flare_api_versions.erl"},
                       {line,22}]},
                  {flare_sup,init,1,
                      [{file,
                           "/Users/lukas/Work/hibase/dependency_bug/deps/flare/src/flare_sup.erl"},
                       {line,25}]},
                  {supervisor,init,1,[{file,"supervisor.erl"},{line,295}]},
                  {gen_server,init_it,2,[{file,"gen_server.erl"},{line,374}]},
                  {gen_server,init_it,6,[{file,"gen_server.erl"},{line,342}]},
                  {proc_lib,init_p_do_apply,3,
                      [{file,"proc_lib.erl"},{line,249}]}]},
             {flare_app,start,[normal,[]]}}
    type: permanent
{"Kernel pid terminated",application_controller,"{application_start_failure,flare,{{undef,[{kpro_req_lib,make,[api_versions,0,[]],[]},{flare_api_versions,api_versions,1,[{file,\"/Users/lukas/Work/hibase/dependency_bug/deps/flare/src/flare_api_versions.erl\"},{line,66}]},{flare_api_versions,init,0,[{file,\"/Users/lukas/Work/hibase/dependency_bug/deps/flare/src/flare_api_versions.erl\"},{line,22}]},{flare_sup,init,1,[{file,\"/Users/lukas/Work/hibase/dependency_bug/deps/flare/src/flare_sup.erl\"},{line,25}]},{supervisor,init,1,[{file,\"supervisor.erl\"},{line,295}]},{gen_server,init_it,2,[{file,\"gen_server.erl\"},{line,374}]},{gen_server,init_it,6,[{file,\"gen_server.erl\"},{line,342}]},{proc_lib,init_p_do_apply,3,[{file,\"proc_lib.erl\"},{line,249}]}]},{flare_app,start,[normal,[]]}}}"}
Kernel pid terminated (application_controller) ({application_start_failure,flare,{{undef,[{kpro_req_lib,make,[api_versions,0,[]],[]},{flare_api_versions,api_versions,1,[{file,"/Users/lukas/Work/hibase

Crash dump is being written to: erl_crash.dump...done

I want to emphasise that kafka protocol is a dependency, that is already declared through flare and fetched by mix in the previous steps.

  defp deps do
    [
      {:flare, git: "https://github.com/lpgauth/flare.git", tag: "0.3.3"},
      {:distillery, "~> 2.0"},
      {:kafka_protocol, git: "https://github.com/klarna/kafka_protocol.git", branch: "master"}
    ]
  end
$ mix deps.get
$ mix compile
$ rm -rf _build
$ MIX_ENV=prod mix release
$ _build/prod/rel/dependency_bug/bin/dependency_bug console
Erlang/OTP 21 [erts-10.3.5] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe] [dtrace]

Interactive Elixir (1.8.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(dependency_bug@127.0.0.1)1>
Application.ensure_all_started(:flare)
{:ok, []}

All because I manually added kafka_protocol to the required dependencies in my mix.exs, although it was there beforehand.

Expected behavior

I expect distillery/elixir to properly resolve dependencies and include everything in my release that is necessary to start the application, just like in development mode.

No surprises like these in production, please.

Kind regards, Lukas Rieder

bitwalker commented 5 years ago

The problem is that flare does not include kafka_protocol (where the "missing" module is found) in its applications list (which can be found under src/flare.app.src), so the release will not carry any of the modules from kafka_protocol as a result.

This is a bug with flare, they should add kafka_protocol to their applications list.