Configure FLUs and chains with "rc.d" style configuration #56
3 changed files with 61 additions and 38 deletions
|
@ -82,7 +82,7 @@
|
||||||
mode :: pv1_consistency_mode(),
|
mode :: pv1_consistency_mode(),
|
||||||
full = [] :: [p_srvr()],
|
full = [] :: [p_srvr()],
|
||||||
witnesses = [] :: [p_srvr()],
|
witnesses = [] :: [p_srvr()],
|
||||||
old_all = [] :: [pv1_server()], % guard against some races
|
old_full = [] :: [pv1_server()], % guard against some races
|
||||||
old_witnesses=[] :: [pv1_server()], % guard against some races
|
old_witnesses=[] :: [pv1_server()], % guard against some races
|
||||||
local_run = [] :: [pv1_server()], % must be tailored to each machine!
|
local_run = [] :: [pv1_server()], % must be tailored to each machine!
|
||||||
local_stop = [] :: [pv1_server()], % must be tailored to each machine!
|
local_stop = [] :: [pv1_server()], % must be tailored to each machine!
|
||||||
|
|
|
@ -355,7 +355,8 @@ bootstrap_chain2(CD, FLU, 0) ->
|
||||||
failed;
|
failed;
|
||||||
bootstrap_chain2(#chain_def_v1{name=NewChainName, mode=NewCMode,
|
bootstrap_chain2(#chain_def_v1{name=NewChainName, mode=NewCMode,
|
||||||
full=Full, witnesses=Witnesses,
|
full=Full, witnesses=Witnesses,
|
||||||
old_all=ReqOldAll, old_witnesses=ReqOldWitnesses,
|
old_full=ReqOldFull,
|
||||||
|
old_witnesses=ReqOldWitnesses,
|
||||||
props=_Props}=CD,
|
props=_Props}=CD,
|
||||||
FLU, N) ->
|
FLU, N) ->
|
||||||
All_p_srvrs = Witnesses ++ Full,
|
All_p_srvrs = Witnesses ++ Full,
|
||||||
|
@ -371,7 +372,7 @@ bootstrap_chain2(#chain_def_v1{name=NewChainName, mode=NewCMode,
|
||||||
all_members=OldAll_list, witnesses=OldWitnesses}} =
|
all_members=OldAll_list, witnesses=OldWitnesses}} =
|
||||||
machi_projection_store:read_latest_projection(PStore, private),
|
machi_projection_store:read_latest_projection(PStore, private),
|
||||||
case set_chain_members(OldChainName, NewChainName, OldCMode,
|
case set_chain_members(OldChainName, NewChainName, OldCMode,
|
||||||
ReqOldAll, ReqOldWitnesses,
|
ReqOldFull, ReqOldWitnesses,
|
||||||
OldAll_list, OldWitnesses,
|
OldAll_list, OldWitnesses,
|
||||||
NewAll_list, Witnesses,
|
NewAll_list, Witnesses,
|
||||||
Mgr, NewChainName, OldEpoch,
|
Mgr, NewChainName, OldEpoch,
|
||||||
|
@ -396,18 +397,18 @@ bootstrap_chain2(#chain_def_v1{name=NewChainName, mode=NewCMode,
|
||||||
end.
|
end.
|
||||||
|
|
||||||
set_chain_members(OldChainName, NewChainName, OldCMode,
|
set_chain_members(OldChainName, NewChainName, OldCMode,
|
||||||
ReqOldAll, ReqOldWitnesses,
|
ReqOldFull, ReqOldWitnesses,
|
||||||
OldAll_list, OldWitnesses, NewAll_list, NewWitnesses,
|
OldFull_list, OldWitnesses, NewAll_list, NewWitnesses,
|
||||||
Mgr, ChainName, OldEpoch, NewCMode, MembersDict, _Props) ->
|
Mgr, ChainName, OldEpoch, NewCMode, MembersDict, _Props) ->
|
||||||
if OldChainName == NewChainName, OldCMode == NewCMode,
|
if OldChainName == NewChainName, OldCMode == NewCMode,
|
||||||
OldAll_list == NewAll_list, OldWitnesses == NewWitnesses ->
|
OldFull_list == NewAll_list, OldWitnesses == NewWitnesses ->
|
||||||
%% The chain's current definition at this FLU is already what we
|
%% The chain's current definition at this FLU is already what we
|
||||||
%% want. Let's pretend that we sent the command and that it was
|
%% want. Let's pretend that we sent the command and that it was
|
||||||
%% successful.
|
%% successful.
|
||||||
ok;
|
ok;
|
||||||
OldEpoch == 0 orelse (OldChainName == NewChainName andalso
|
OldEpoch == 0 orelse (OldChainName == NewChainName andalso
|
||||||
OldCMode == NewCMode andalso
|
OldCMode == NewCMode andalso
|
||||||
ReqOldAll == OldAll_list andalso
|
ReqOldFull == OldFull_list andalso
|
||||||
ReqOldWitnesses == OldWitnesses) ->
|
ReqOldWitnesses == OldWitnesses) ->
|
||||||
%% The old epoch is 0 (no chain defined) or else the prerequisites
|
%% The old epoch is 0 (no chain defined) or else the prerequisites
|
||||||
%% for our chain change request are indeed matched by the FLU's
|
%% for our chain change request are indeed matched by the FLU's
|
||||||
|
@ -641,14 +642,14 @@ check_an_ast_tuple({host, Name, AdminI, ClientI, Props}) ->
|
||||||
check_an_ast_tuple({flu, Name, HostName, Port, Props}) ->
|
check_an_ast_tuple({flu, Name, HostName, Port, Props}) ->
|
||||||
is_stringy(Name) andalso is_stringy(HostName) andalso
|
is_stringy(Name) andalso is_stringy(HostName) andalso
|
||||||
is_porty(Port) andalso is_proplisty(Props);
|
is_porty(Port) andalso is_proplisty(Props);
|
||||||
check_an_ast_tuple({chain, Name, AllList, Props}) ->
|
check_an_ast_tuple({chain, Name, FullList, Props}) ->
|
||||||
is_stringy(Name) andalso
|
is_stringy(Name) andalso
|
||||||
lists:all(fun is_stringy/1, AllList) andalso
|
lists:all(fun is_stringy/1, FullList) andalso
|
||||||
is_proplisty(Props);
|
is_proplisty(Props);
|
||||||
check_an_ast_tuple({chain, Name, CMode, AllList, Witnesses, Props}) ->
|
check_an_ast_tuple({chain, Name, CMode, FullList, Witnesses, Props}) ->
|
||||||
is_stringy(Name) andalso
|
is_stringy(Name) andalso
|
||||||
(CMode == ap_mode orelse CMode == cp_mode) andalso
|
(CMode == ap_mode orelse CMode == cp_mode) andalso
|
||||||
lists:all(fun is_stringy/1, AllList) andalso
|
lists:all(fun is_stringy/1, FullList) andalso
|
||||||
lists:all(fun is_stringy/1, Witnesses) andalso
|
lists:all(fun is_stringy/1, Witnesses) andalso
|
||||||
is_proplisty(Props);
|
is_proplisty(Props);
|
||||||
check_an_ast_tuple(switch_old_and_new) ->
|
check_an_ast_tuple(switch_old_and_new) ->
|
||||||
|
@ -673,10 +674,10 @@ normalize_an_ast_tuple({host, Name, AdminI, ClientI, Props}) ->
|
||||||
{host, Name, AdminI, ClientI, n(Props2)};
|
{host, Name, AdminI, ClientI, n(Props2)};
|
||||||
normalize_an_ast_tuple({flu, Name, HostName, Port, Props}) ->
|
normalize_an_ast_tuple({flu, Name, HostName, Port, Props}) ->
|
||||||
{flu, Name, HostName, Port, n(Props)};
|
{flu, Name, HostName, Port, n(Props)};
|
||||||
normalize_an_ast_tuple({chain, Name, AllList, Props}) ->
|
normalize_an_ast_tuple({chain, Name, FullList, Props}) ->
|
||||||
{chain, Name, ap_mode, n(AllList), [], n(Props)};
|
{chain, Name, ap_mode, n(FullList), [], n(Props)};
|
||||||
normalize_an_ast_tuple({chain, Name, CMode, AllList, Witnesses, Props}) ->
|
normalize_an_ast_tuple({chain, Name, CMode, FullList, Witnesses, Props}) ->
|
||||||
{chain, Name, CMode, n(AllList), n(Witnesses), n(Props)};
|
{chain, Name, CMode, n(FullList), n(Witnesses), n(Props)};
|
||||||
normalize_an_ast_tuple(A=switch_old_and_new) ->
|
normalize_an_ast_tuple(A=switch_old_and_new) ->
|
||||||
A.
|
A.
|
||||||
|
|
||||||
|
@ -701,14 +702,16 @@ run_ast(Ts) ->
|
||||||
%% Mutable: no.
|
%% Mutable: no.
|
||||||
%% Reference KV store for X. Variations of X are:
|
%% Reference KV store for X. Variations of X are:
|
||||||
%% {host, Name} | {flu, Name} | {chain, Name}
|
%% {host, Name} | {flu, Name} | {chain, Name}
|
||||||
|
%% Value is a {host,...} or {flu,...}, or {chain,...} AST tuple.
|
||||||
%%
|
%%
|
||||||
%% {tmp, X}
|
|
||||||
%% Mutable: yes.
|
|
||||||
%% Tmp scratch for X. Variations of X are:
|
|
||||||
%% {p_srvr, Name}
|
%% {p_srvr, Name}
|
||||||
%% #p_srvr{} record for FLU Name, for cache/convenience purposes.
|
%% #p_srvr{} record for FLU Name, for cache/convenience purposes.
|
||||||
%% If a FLU has been defined via {kv,_}, this key must also exist.
|
%% If a FLU has been defined via {kv,_}, this key must also exist.
|
||||||
%%
|
%%
|
||||||
|
%%
|
||||||
|
%% {tmp, X}
|
||||||
|
%% Mutable: yes.
|
||||||
|
%% Tmp scratch for X. Variations of X are:
|
||||||
%% {flu_assigned_to, ChainName}
|
%% {flu_assigned_to, ChainName}
|
||||||
%% If a FLU is currently assigned to a chain, map to ChainName.
|
%% If a FLU is currently assigned to a chain, map to ChainName.
|
||||||
%% If a FLU is not currently assigned to a chain, key does not exist.
|
%% If a FLU is not currently assigned to a chain, key does not exist.
|
||||||
|
@ -732,7 +735,7 @@ run_ast_cmd({flu, Name, HostName, Port, Props}=T, E) ->
|
||||||
{ok, ClientI} = get_host_client_interface(HostName, E),
|
{ok, ClientI} = get_host_client_interface(HostName, E),
|
||||||
Mod = proplists:get_value(
|
Mod = proplists:get_value(
|
||||||
proto_mod, Props, 'machi_flu1_client'),
|
proto_mod, Props, 'machi_flu1_client'),
|
||||||
Val_p = #p_srvr{name=Name, proto_mod=Mod,
|
Val_p = #p_srvr{name=list_to_atom(Name), proto_mod=Mod,
|
||||||
address=ClientI, port=Port, props=Props},
|
address=ClientI, port=Port, props=Props},
|
||||||
d_store(Key, T,
|
d_store(Key, T,
|
||||||
d_store(Key_p, Val_p, E));
|
d_store(Key_p, Val_p, E));
|
||||||
|
@ -745,9 +748,9 @@ run_ast_cmd({flu, Name, HostName, Port, Props}=T, E) ->
|
||||||
{ok, _} ->
|
{ok, _} ->
|
||||||
err("Duplicate flu ~p", [Name], T)
|
err("Duplicate flu ~p", [Name], T)
|
||||||
end;
|
end;
|
||||||
run_ast_cmd({chain, Name, CMode, AllList, Witnesses, _Props}=T, E) ->
|
run_ast_cmd({chain, Name, CMode, FullList, Witnesses, _Props}=T, E) ->
|
||||||
Key = {kv,{chain,Name}},
|
Key = {kv,{chain,Name}},
|
||||||
AllFLUs = AllList ++ Witnesses,
|
AllFLUs = FullList ++ Witnesses,
|
||||||
|
|
||||||
%% All FLUs must exist.
|
%% All FLUs must exist.
|
||||||
case lists:sort(AllFLUs) == lists:usort(AllFLUs) of
|
case lists:sort(AllFLUs) == lists:usort(AllFLUs) of
|
||||||
|
@ -858,6 +861,7 @@ d_find(Key, {KV_old, KV_new, IsNew}) ->
|
||||||
|
|
||||||
d_get(Key, {KV_old, KV_new, IsNew}) ->
|
d_get(Key, {KV_old, KV_new, IsNew}) ->
|
||||||
%% Bah, use 'dict' return value convention.
|
%% Bah, use 'dict' return value convention.
|
||||||
|
%% Assume key exists, fail if not found.
|
||||||
case gb_trees:lookup(Key, KV_new) of
|
case gb_trees:lookup(Key, KV_new) of
|
||||||
{value, Val} when IsNew ->
|
{value, Val} when IsNew ->
|
||||||
Val;
|
Val;
|
||||||
|
@ -924,12 +928,12 @@ diff_env({KV_old, KV_new, _IsNew}=E, RelativeHost) ->
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
DiffD = lists:foldl(fun(K, D) ->
|
%% DiffD = lists:foldl(fun(K, D) ->
|
||||||
gb_trees:enter(K, [], D)
|
%% gb_trees:enter(K, [], D)
|
||||||
end, gb_trees:empty(), lists:usort(Keys_old++Keys_new)),
|
%% end, gb_trees:empty(), lists:usort(Keys_old++Keys_new)),
|
||||||
DiffD2 = lists:foldl(Append(old), DiffD, Keys_old),
|
%% DiffD2 = lists:foldl(Append(old), DiffD, Keys_old),
|
||||||
DiffD3 = lists:foldl(Append(new), DiffD2, Keys_new),
|
%% DiffD3 = lists:foldl(Append(new), DiffD2, Keys_new),
|
||||||
%% DiffD3 values will be exactly one of: [old], [old,new], [new]
|
%% %% DiffD3 values will be exactly one of: [old], [old,new], [new]
|
||||||
|
|
||||||
put(final, []),
|
put(final, []),
|
||||||
Add = fun(X) -> put(final, [X|get(final)]) end,
|
Add = fun(X) -> put(final, [X|get(final)]) end,
|
||||||
|
@ -946,23 +950,42 @@ diff_env({KV_old, KV_new, _IsNew}=E, RelativeHost) ->
|
||||||
%% Find new chains on this host and define them.
|
%% Find new chains on this host and define them.
|
||||||
%% Find modified chains on this host and re-define them.
|
%% Find modified chains on this host and re-define them.
|
||||||
[begin
|
[begin
|
||||||
{chain, Name, CMode, AllList, Witnesses, Props} = V,
|
{chain, Name, CMode, FullList, Witnesses, Props} = V,
|
||||||
FLUsA = [d_get({kv,{flu,FLU}}, E) || FLU <- AllList],
|
FLUsF = [d_get({kv,{flu,FLU}}, E) || FLU <- FullList],
|
||||||
FLUsW = [d_get({kv,{flu,FLU}}, E) || FLU <- Witnesses],
|
FLUsW = [d_get({kv,{flu,FLU}}, E) || FLU <- Witnesses],
|
||||||
TheFLU_Hosts =
|
TheFLU_Hosts = [{list_to_atom(FLU_str), Host} ||
|
||||||
[Host || {flu, _Name, Host, _Port, _Ps} <- FLUsA ++ FLUsW],
|
{flu, FLU_str, Host, _Port, _Ps} <- FLUsF ++ FLUsW],
|
||||||
case (lists:member(RelativeHost, TheFLU_Hosts)
|
case (lists:keymember(RelativeHost, 2, TheFLU_Hosts)
|
||||||
orelse RelativeHost == all) of
|
orelse RelativeHost == all) of
|
||||||
true ->
|
true ->
|
||||||
|
Ps_F = [d_get({kv,{p_srvr,FLU}}, E) || FLU <- FullList],
|
||||||
|
Ps_W = [d_get({kv,{p_srvr,FLU}}, E) || FLU <- Witnesses],
|
||||||
|
|
||||||
case gb_trees:lookup({kv,{chain,Name}}, KV_old) of
|
case gb_trees:lookup({kv,{chain,Name}}, KV_old) of
|
||||||
{value, OldT} ->
|
{value, OldT} ->
|
||||||
Add({yo,change,Name});
|
{chain, _, _, OldFull_ss, OldWitnesses_ss, _} = OldT,
|
||||||
|
OldFull = [Str || Str <- OldFull_ss],
|
||||||
|
OldWitnesses = [Str || Str <- OldWitnesses_ss],
|
||||||
|
io:format(user, "\nOldT: ~p\n", [OldT]),
|
||||||
|
Run = [FLU || {FLU, Hst} <- TheFLU_Hosts,
|
||||||
|
Hst == RelativeHost
|
||||||
|
orelse RelativeHost == all,
|
||||||
|
not lists:member(FLU,
|
||||||
|
OldFull++OldWitnesses)],
|
||||||
|
Stop = [yolo];
|
||||||
none ->
|
none ->
|
||||||
Add({yo,new,Name})
|
OldFull = [],
|
||||||
end;
|
OldWitnesses = [],
|
||||||
|
Run = [derp,derp],
|
||||||
|
Stop = []
|
||||||
|
end,
|
||||||
|
Add(#chain_def_v1{name=list_to_atom(Name),
|
||||||
|
mode=CMode, full=Ps_F, witnesses=Ps_W,
|
||||||
|
old_full=OldFull, old_witnesses=OldWitnesses,
|
||||||
|
local_run=Run, local_stop=Stop});
|
||||||
false ->
|
false ->
|
||||||
ok
|
ok
|
||||||
end
|
end
|
||||||
end || {{kv,{chain,Name}}, V} <- New_list],
|
end || {{kv,{chain,Name}}, V} <- New_list],
|
||||||
|
|
||||||
{DiffD3, lists:reverse(get(final))}.
|
{gb_trees:empty(), lists:reverse(get(final))}.
|
||||||
|
|
|
@ -107,7 +107,7 @@ smoke_test2() ->
|
||||||
io:format("\nSTEP: Reset chain = [b,c]\n", []),
|
io:format("\nSTEP: Reset chain = [b,c]\n", []),
|
||||||
|
|
||||||
C2 = #chain_def_v1{name=cx, mode=ap_mode, full=[Pb,Pc],
|
C2 = #chain_def_v1{name=cx, mode=ap_mode, full=[Pb,Pc],
|
||||||
old_all=[a,b,c], old_witnesses=[],
|
old_full=[a,b,c], old_witnesses=[],
|
||||||
local_stop=[a], local_run=[b,c]},
|
local_stop=[a], local_run=[b,c]},
|
||||||
make_pending_config(C2),
|
make_pending_config(C2),
|
||||||
{[],[_]} = machi_lifecycle_mgr:process_pending(),
|
{[],[_]} = machi_lifecycle_mgr:process_pending(),
|
||||||
|
@ -123,7 +123,7 @@ smoke_test2() ->
|
||||||
io:format("\nSTEP: Reset chain = []\n", []),
|
io:format("\nSTEP: Reset chain = []\n", []),
|
||||||
|
|
||||||
C3 = #chain_def_v1{name=cx, mode=ap_mode, full=[],
|
C3 = #chain_def_v1{name=cx, mode=ap_mode, full=[],
|
||||||
old_all=[b,c], old_witnesses=[],
|
old_full=[b,c], old_witnesses=[],
|
||||||
local_stop=[b,c], local_run=[]},
|
local_stop=[b,c], local_run=[]},
|
||||||
make_pending_config(C3),
|
make_pending_config(C3),
|
||||||
{[],[_]} = machi_lifecycle_mgr:process_pending(),
|
{[],[_]} = machi_lifecycle_mgr:process_pending(),
|
||||||
|
|
Loading…
Reference in a new issue