Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

upgrade to a new release without a relup or rebooting the VM #1581

Closed
wants to merge 3 commits into from

Conversation

tsloughter
Copy link
Contributor

This function provides a way to go to a new release in the case you want to just do a restart and not a live upgrade but without rebooting the VM or requiring any appups or relup.

It includes the patch from #1580 as well because it partially needs it (at least to work smoothly when using release tarballs generated by relx) but I consider #1580 important on its own and separate as well.

@sirihansen
Copy link
Contributor

This seems interesting, and we would like to discuss it a bit in the team. Could you please provide some more background and use cases for this? Do you think this is a functionality that would be preferred in many cases, compared to the more cumbersome hot upgrade?

#release.status,
Releases) of
false ->
lists:keysearch(current,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realize that this is copied from another function in this module, but still... if this clause is hit, it will break further down in this function since CurrentRunning then will be either {value,#release{}} or false. If we decide to accept this PR, then please correct both places (or even refactor to avoid the duplicated code).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'll look at this later today.

@tsloughter
Copy link
Contributor Author

I know this is something I would have been using if it existed before all my deploys became containers that are created/deleted for deploys instead of starting a new release next to the current release. For those times that you do deploy the new release to the same node, and you don't need a hot upgrade, it makes sense to not have to do a stop and start of the whole erlang node and to have it be a built in command.

@sirihansen
Copy link
Contributor

Still finding this interesting, but could you explain a bit what is the main idea behind using init:restart/0 instead of init:reboot/0? The thing is, I can't really see how it would work. init:restart/0 restarts the system exactly the same way as it was first started, using the same BootArgs, so we get the same .boot file, causing the same old versions of your applications to be started. I think at least you would have to call init:make_permanent/2 in order to update the init process' view on which -boot and -config flags to use. But I still wonder if it wouldn't be easier to use init:reboot/0, though?

I also think that we must consider what to do if

  • erts version differs between the releases
  • a relup file exists in the new release - should we ignore it? warn? fail?
  • application environment variables have been changed during runtime - should we do any attempt at keeping them over this upgrade?

@sirihansen
Copy link
Contributor

Of course, init:reboot/0 requires heart, which init:restart/0doesn't... so that might be a reason...

@sirihansen sirihansen added the waiting waiting for changes/input from author label Dec 20, 2017
@tsloughter
Copy link
Contributor Author

Sorry for the delay.

It does set it to permanent before the restart. And seems to work fine.

Yea, reboot requires heart but also adds the time of VM startup. But I think the main point would be that even with reboot there still should be a function that reboots to the new release.

@sirihansen sirihansen removed the waiting waiting for changes/input from author label Jan 15, 2018
@sirihansen
Copy link
Contributor

sirihansen commented Jan 15, 2018

Now I've been testing a bit, but I don't really get it to work. The release_handler does see the second version as permanent after the restart, but the code actually running is still the first version, and init still sees the first version's sys.config and start.boot:

1> {ok,Vsn} = release_handler:unpack_release("mysystem2").
{ok,"SECOND"}
2> release_handler:which_releases().        
[{"MYSYSTEM","SECOND",
  ["kernel-5.3.1","stdlib-3.4.1","sasl-3.0.4","pea-2.0"],
  unpacked},
 {"MYSYSTEM","FIRST",
  ["kernel-5.3.1","stdlib-3.4.1","sasl-3.0.4","pea-1.0"],
  permanent}]
3> code:which(pea_app).
"/home/uabshan/Work/experiment/restart_new_release/target/lib/pea-1.0/ebin/pea_app.beam"
4> init:get_arguments().
[{root,["/home/uabshan/Work/experiment/restart_new_release/target"]},
 {progname,["start_erl"]},
 {home,["/home/uabshan"]},
 {boot,["/home/uabshan/Work/experiment/restart_new_release/target/releases/FIRST/start"]},
 {config,["/home/uabshan/Work/experiment/restart_new_release/target/releases/FIRST/sys"]},
 {kernel,["shell_history","enabled"]}]
5> release_handler:restart_new_release(Vsn).
ok
6> Erlang/OTP 20 [erts-9.0.5] [source-ac9427c] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]

=PROGRESS REPORT==== 15-Jan-2018::12:10:21 ===
          supervisor: {local,sasl_safe_sup}
             started: [{pid,<0.151.0>},
                       {id,alarm_handler},
                       {mfargs,{alarm_handler,start_link,[]}},
                       {restart_type,permanent},
                       {shutdown,2000},
                       {child_type,worker}]

[snip...]

=PROGRESS REPORT==== 15-Jan-2018::12:10:21 ===
         application: pea
          started_at: nonode@nohost
Eshell V9.0.5  (abort with ^G)
1> 
1> release_handler:which_releases().        
[{"MYSYSTEM","SECOND",
  ["kernel-5.3.1","stdlib-3.4.1","sasl-3.0.4","pea-2.0"],
  permanent},
 {"MYSYSTEM","FIRST",
  ["kernel-5.3.1","stdlib-3.4.1","sasl-3.0.4","pea-1.0"],
  old}]
2> application:which_applications().
[{pea,"Target System App","1.0"},
 {sasl,"SASL  CXC 138 11","3.0.4"},
 {stdlib,"ERTS  CXC 138 10","3.4.1"}, 
 {kernel,"ERTS  CXC 138 10","5.3.1"}]
3> code:which(pea_app).                     
"/home/uabshan/Work/experiment/restart_new_release/target/lib/pea-1.0/ebin/pea_app.beam"
4> init:get_arguments().                    
[{root,["/home/uabshan/Work/experiment/restart_new_release/target"]},
 {progname,["start_erl"]},
 {home,["/home/uabshan"]},
 {boot,["/home/uabshan/Work/experiment/restart_new_release/target/releases/FIRST/start"]},
 {config,["/home/uabshan/Work/experiment/restart_new_release/target/releases/FIRST/sys"]},
 {kernel,["shell_history","enabled"]}]

And also the other questions from this comment still apply...

@sirihansen sirihansen added the waiting waiting for changes/input from author label Jan 22, 2018
@sirihansen
Copy link
Contributor

@tsloughter Anything new on this? Or should I close it?

@tsloughter
Copy link
Contributor Author

Na, I'll close this.

@tsloughter tsloughter closed this Jan 16, 2019
@sirihansen sirihansen removed the waiting waiting for changes/input from author label Jan 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants