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
Closed
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
72 changes: 69 additions & 3 deletions lib/sasl/src/release_handler.erl
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
check_install_release/1, check_install_release/2,
install_release/1, install_release/2, new_emulator_upgrade/2,
remove_release/1, which_releases/0, which_releases/1,
make_permanent/1, reboot_old_release/1,
make_permanent/1, reboot_old_release/1, restart_new_release/1,
set_unpacked/2, set_removed/1, install_file/2]).
-export([upgrade_app/2, downgrade_app/2, downgrade_app/3,
upgrade_script/2, downgrade_script/3,
Expand Down Expand Up @@ -278,6 +278,12 @@ make_permanent(Vsn) ->
reboot_old_release(Vsn) ->
call({reboot_old_release, Vsn}).

%%-----------------------------------------------------------------
%% Purpose: Restarts the system from a new release.
%%-----------------------------------------------------------------
restart_new_release(Vsn) ->
call({restart_new_release, Vsn}).

%%-----------------------------------------------------------------
%% Purpose: Deletes all files and directories used by the release
%% version, that are not used by any other release.
Expand Down Expand Up @@ -674,6 +680,18 @@ handle_call({reboot_old_release, Vsn}, From, S) ->
{reply, {error, Reason}, S}
end;

handle_call({restart_new_release, Vsn}, From, S) ->
case catch do_restart_new_release(S, Vsn) of
ok ->
gen_server:reply(From, ok),
init:restart(),
{noreply, S};
{error, Reason} ->
{reply, {error, Reason}, S};
{'EXIT', Reason} ->
{reply, {error, Reason}, S}
end;

handle_call({remove_release, Vsn}, _From, S)
when S#state.masters == false ->
case catch do_remove_release(S#state.root, S#state.rel_dir,
Expand Down Expand Up @@ -847,11 +865,18 @@ do_unpack_release(Root, RelDir, ReleaseName, Releases) ->
%% systools:make_tar, where there is no copy of the .rel file in
%% the releases/<vsn> dir. See OTP-9746.
Dir = filename:join([RelDir, Vsn]),
copy_file(RelFile, Dir, false),

%% don't copy or delete RelFile if it is already under releases/<vsn>
_ = case filename:dirname(RelFile) of
Dir ->
ok;
_ ->
copy_file(RelFile, Dir, false),
_ = file:delete(RelFile)
end,

%% Clean release
_ = file:delete(Tar),
_ = file:delete(RelFile),

{ok, NewReleases, Vsn}.

Expand Down Expand Up @@ -1363,6 +1388,47 @@ do_reboot_old_release(#state{releases = Releases,
{error, {no_such_release, Vsn}}
end.

do_restart_new_release(#state{releases = Releases,
rel_dir = RelDir, masters = Masters,
static_emulator = Static},
Vsn) ->
case lists:keysearch(Vsn, #release.vsn, Releases) of
{value, #release{erts_vsn = EVsn, status = unpacked}} ->
CurrentRunning = case os:type() of
{win32,nt} ->
%% Get the current release on NT
case lists:keysearch(permanent,
#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.

#release.status,
Releases);
{value,CR} ->
CR
end;
_ ->
false
end,
set_permanent_files(RelDir, EVsn, Vsn, Masters, Static),
NewReleases = set_status(Vsn, permanent, Releases),
write_releases(RelDir, NewReleases, Masters),
case os:type() of
{win32,nt} ->
%% Edit up the services and set a reasonable heart
%% command
do_back_service(Vsn,CurrentRunning#release.vsn,EVsn,
CurrentRunning#release.erts_vsn);
_ ->
ok
end,
ok;
{value, #release{status = Status}} ->
{error, {bad_status, Status}};
false ->
{error, {no_such_release, Vsn}}
end.

%%-----------------------------------------------------------------
%% Depending of if the release_handler is running in normal, client or
%% client with static emulator the new system version is made permanent
Expand Down