bitwalker / distillery

Simplify deployments in Elixir with OTP releases!
MIT License
2.96k stars 396 forks source link

Post upgrade hooks operate on previous version #654

Closed pierot closed 5 years ago

pierot commented 5 years ago

Steps to reproduce

I have several post_upgrade_hooks and post_start hooks: migrate, seed and symlink_assets. The tasks are defined in MyApp.ReleaseTasks from the shell scripts:

Example .sh:

#!/bin/sh
release_ctl eval --mfa "MyApp.ReleaseTasks.symlink_assets/1" --argv -- "$@"

config.exs:

environment :staging do
  set(include_erts: true)
  set(include_src: false)
  set(cookie: :"XXX")
  set(vm_args: "rel/vm.args.staging.eex")

  set(post_start_hooks: "rel/hooks/post_start")
  set(post_upgrade_hooks: "rel/hooks/post_start")
end

symlink_assets task:

  def symlink_assets(_argv) do
    start_services()

    IO.puts("Symlink assets")

    priv_path = "#{:code.priv_dir(@app)}/static"
    pwd = :os.cmd(String.to_char_list("pwd"))
    static_path = "#{pwd}/static"

    cmd = "ln -sfn #{priv_path} #{static_path} 2>/dev/null"

    IO.puts("`#{cmd}`")

    cmd |> String.to_char_list() |> :os.cmd()

    stop_services()
  end

Verbose Logs

Symlink assets
`ln -sfn /app/myapp/lib/myapp-0.5.1+2010-431cb0f0-develop/priv/static /app/myapp
/static 2>/dev/null`
Success!
Checking upgraded version on host XXX
Version 0.5.1+2011-4d4fe986-develop is installed on host XXX

Even calling the command on the server produces a path for the previous release:

$ ./myapp symlink_assets

Starting dependencies...
Starting repos...
Symlink assets
`ln -sfn /app/myapp/lib/myapp-0.5.1+2010-431cb0f0-develop/priv/static /app/myapp
/static 2>/dev/null`
Success!

Description of issue

bitwalker commented 5 years ago

I've pushed a fix for this, since I believe what you are expecting is probably correct, but it isn't quite as black and white as it seems.

The issue is that when a release is installed, we're still running the old versions upgrade scripts, which are still pointing to the old release, code paths as well. In this case, your custom task is running using the old versions code, which in some situations likely makes a lot of sense. On the other hand, it means that any post_upgrade hooks in the new release aren't executed until it is being upgraded from.

I believe the most intuitive thing here is what you expect, that the post upgrade hook is run using new code, but I can see the potential for that to be a problem. I suspect nobody has noticed this so far, as they probably aren't doing anything that sensitive to paths in those hooks, and you happen to be the first to have hit the issue.

In any case, this fix is available on both master and 2.0.x branches; the next release will be 2.1.0 from master, so if you want the fix without making the changes necessary to get Elixir 1.9 comptability, then update your distillery dep to point to the 2.0.x branch, which will be getting maintenance fixes from now on.