diff options
author | Matthew Sackman <matthew@rabbitmq.com> | 2011-03-17 00:52:11 +0000 |
---|---|---|
committer | Matthew Sackman <matthew@rabbitmq.com> | 2011-03-17 00:52:11 +0000 |
commit | 221433535cd1551a83132d0a8d46440dd12ea433 (patch) | |
tree | 465b6190105ee0b0ac282a9bdd60d73b74f38407 /src/rabbit_upgrade.erl | |
parent | f10c0b62e57dd2e5d0f2dd877e03dfd699298cc9 (diff) | |
download | rabbitmq-server-221433535cd1551a83132d0a8d46440dd12ea433.tar.gz |
incorporate qa feedback. The version.erl api is rather nice now: the version itself is entirely opaque - whilst it can be read, there's nothing provided to decompose it at all.
Diffstat (limited to 'src/rabbit_upgrade.erl')
-rw-r--r-- | src/rabbit_upgrade.erl | 116 |
1 files changed, 20 insertions, 96 deletions
diff --git a/src/rabbit_upgrade.erl b/src/rabbit_upgrade.erl index 9b2ffa28..9347cc53 100644 --- a/src/rabbit_upgrade.erl +++ b/src/rabbit_upgrade.erl @@ -17,13 +17,11 @@ -module(rabbit_upgrade). -export([maybe_upgrade_mnesia/0, maybe_upgrade_local/0]). --export([desired_version/0]). -include("rabbit.hrl"). -define(VERSION_FILENAME, "schema_version"). -define(LOCK_FILENAME, "schema_upgrade_lock"). --define(SCOPES, [mnesia, local]). %% ------------------------------------------------------------------- @@ -31,7 +29,6 @@ -spec(maybe_upgrade_mnesia/0 :: () -> 'ok'). -spec(maybe_upgrade_local/0 :: () -> 'ok' | 'version_not_available'). --spec(desired_version/0 :: () -> rabbit_version:version()). -endif. @@ -96,8 +93,8 @@ maybe_upgrade_mnesia() -> AllNodes = rabbit_mnesia:all_clustered_nodes(), - case upgrades_required(mnesia) of - version_not_available -> + case rabbit_version:upgrades_required(mnesia) of + {error, version_not_available} -> rabbit:prepare(), %% Ensure we have logs for this case AllNodes of [_] -> ok; @@ -105,9 +102,11 @@ maybe_upgrade_mnesia() -> "< 2.1.1.~nUnfortunately you will need to " "rebuild the cluster.", []) end; - [] -> + {error, _} = Err -> + throw(Err); + {ok, []} -> ok; - Upgrades -> + {ok, Upgrades} -> rabbit:prepare(), %% Ensure we have logs for this case upgrade_mode(AllNodes) of primary -> primary_upgrade(Upgrades, AllNodes); @@ -142,18 +141,19 @@ upgrade_mode(AllNodes) -> end; [Another|_] -> ClusterVersion = - case rpc:call(Another, - rabbit_upgrade, desired_version, [mnesia]) of + case rpc:call(Another, rabbit_version, desired_scope_version, + [mnesia]) of {badrpc, {'EXIT', {undef, _}}} -> unknown_old_version; {badrpc, Reason} -> {unknown, Reason}; V -> V end, - case desired_version(mnesia) of - ClusterVersion -> + MyVersion = rabbit_version:desired_scope_version(mnesia), + case rabbit_version:'=~='(ClusterVersion, MyVersion) of + true -> %% The other node(s) have upgraded already, I am not the %% upgrader secondary; - MyVersion -> + false -> %% The other node(s) are running an unexpected version. die("Cluster upgrade needed but other nodes are " "running ~p~nand I want ~p", @@ -208,7 +208,7 @@ secondary_upgrade(AllNodes) -> end, rabbit_misc:ensure_ok(mnesia:start(), cannot_start_mnesia), ok = rabbit_mnesia:init_db(ClusterNodes, true), - ok = write_desired_scope_version(mnesia), + ok = rabbit_version:write_desired_scope_version(mnesia), ok. nodes_running(Nodes) -> @@ -223,90 +223,14 @@ node_running(Node) -> %% ------------------------------------------------------------------- maybe_upgrade_local() -> - case upgrades_required(local) of - version_not_available -> version_not_available; - [] -> ok; - Upgrades -> apply_upgrades(local, Upgrades, - fun() -> ok end) + case rabbit_version:upgrades_required(local) of + {error, version_not_available} -> version_not_available; + {error, _} = Err -> throw(Err); + {ok, []} -> ok; + {ok, Upgrades} -> apply_upgrades(local, Upgrades, + fun () -> ok end) end. -desired_version() -> [{Scope, desired_version(Scope)} || Scope <- ?SCOPES]. - -desired_version(Scope) -> with_upgrade_graph(fun (G) -> heads(G) end, Scope). - -write_desired_scope_version(Scope) -> - ok = rabbit_version:with_scope_version( - Scope, - fun ({error, Error}) -> - throw({error, {cannot_read_version_to_write_it, Error}}) - end, - fun (_SV) -> {desired_version(Scope), ok} end). - -%% ------------------------------------------------------------------- - -upgrades_required(Scope) -> - rabbit_version:with_scope_version( - Scope, - fun ({error, enoent}) -> version_not_available end, - fun (CurrentHeads) -> - {CurrentHeads, - with_upgrade_graph( - fun (G) -> - case unknown_heads(CurrentHeads, G) of - [] -> - upgrades_to_apply(CurrentHeads, G); - Unknown -> - throw({error, - {future_upgrades_found, Unknown}}) - end - end, Scope)} - end). - -with_upgrade_graph(Fun, Scope) -> - case rabbit_misc:build_acyclic_graph( - fun (Module, Steps) -> vertices(Module, Steps, Scope) end, - fun (Module, Steps) -> edges(Module, Steps, Scope) end, - rabbit_misc:all_module_attributes(rabbit_upgrade)) of - {ok, G} -> try - Fun(G) - after - true = digraph:delete(G) - end; - {error, {vertex, duplicate, StepName}} -> - throw({error, {duplicate_upgrade_step, StepName}}); - {error, {edge, {bad_vertex, StepName}, _From, _To}} -> - throw({error, {dependency_on_unknown_upgrade_step, StepName}}); - {error, {edge, {bad_edge, StepNames}, _From, _To}} -> - throw({error, {cycle_in_upgrade_steps, StepNames}}) - end. - -vertices(Module, Steps, Scope0) -> - [{StepName, {Module, StepName}} || {StepName, Scope1, _Reqs} <- Steps, - Scope0 == Scope1]. - -edges(_Module, Steps, Scope0) -> - [{Require, StepName} || {StepName, Scope1, Requires} <- Steps, - Require <- Requires, - Scope0 == Scope1]. -unknown_heads(Heads, G) -> - [H || H <- Heads, digraph:vertex(G, H) =:= false]. - -upgrades_to_apply(Heads, G) -> - %% Take all the vertices which can reach the known heads. That's - %% everything we've already applied. Subtract that from all - %% vertices: that's what we have to apply. - Unsorted = sets:to_list( - sets:subtract( - sets:from_list(digraph:vertices(G)), - sets:from_list(digraph_utils:reaching(Heads, G)))), - %% Form a subgraph from that list and find a topological ordering - %% so we can invoke them in order. - [element(2, digraph:vertex(G, StepName)) || - StepName <- digraph_utils:topsort(digraph_utils:subgraph(G, Unsorted))]. - -heads(G) -> - lists:sort([V || V <- digraph:vertices(G), digraph:out_degree(G, V) =:= 0]). - %% ------------------------------------------------------------------- apply_upgrades(Scope, Upgrades, Fun) -> @@ -329,7 +253,7 @@ apply_upgrades(Scope, Upgrades, Fun) -> [apply_upgrade(Scope, Upgrade) || Upgrade <- Upgrades], info("~s upgrades: All upgrades applied successfully~n", [Scope]), - ok = write_desired_scope_version(Scope), + ok = rabbit_version:write_desired_scope_version(Scope), ok = rabbit_misc:recursive_delete([BackupDir]), info("~s upgrades: Mnesia backup removed~n", [Scope]), ok = file:delete(LockFile); |